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 * Why is the Fovf descriptor bit set for every received packet? 7 * Occasionally the hardware indicates an input TCP checksum error 8 * although the higher-level software seems to check the packet OK? 9 * No tuning has been done. Only tested on an RTL8110S, there 10 * are slight differences between the chips in the series so some 11 * tweaks may be needed. 12 */ 13 #include "u.h" 14 #include "lib.h" 15 #include "mem.h" 16 #include "dat.h" 17 #include "fns.h" 18 #include "io.h" 19 20 typedef struct QLock { int r; } QLock; 21 #define qlock(i) while(0) 22 #define qunlock(i) while(0) 23 #define iallocb allocb 24 #define iprint print 25 #define mallocalign(n, a, o, s) ialloc((n), (a)) 26 27 #include "etherif.h" 28 #include "ethermii.h" 29 30 enum { /* registers */ 31 Idr0 = 0x00, /* MAC address */ 32 Mar0 = 0x08, /* Multicast address */ 33 Dtccr = 0x10, /* Dump Tally Counter Command */ 34 Tnpds = 0x20, /* Transmit Normal Priority Descriptors */ 35 Thpds = 0x28, /* Transmit High Priority Descriptors */ 36 Flash = 0x30, /* Flash Memory Read/Write */ 37 Erbcr = 0x34, /* Early Receive Byte Count */ 38 Ersr = 0x36, /* Early Receive Status */ 39 Cr = 0x37, /* Command Register */ 40 Tppoll = 0x38, /* Transmit Priority Polling */ 41 Imr = 0x3C, /* Interrupt Mask */ 42 Isr = 0x3E, /* Interrupt Status */ 43 Tcr = 0x40, /* Transmit Configuration */ 44 Rcr = 0x44, /* Receive Configuration */ 45 Tctr = 0x48, /* Timer Count */ 46 Mpc = 0x4C, /* Missed Packet Counter */ 47 Cr9346 = 0x50, /* 9346 Command Register */ 48 Config0 = 0x51, /* Configuration Register 0 */ 49 Config1 = 0x52, /* Configuration Register 1 */ 50 Config2 = 0x53, /* Configuration Register 2 */ 51 Config3 = 0x54, /* Configuration Register 3 */ 52 Config4 = 0x55, /* Configuration Register 4 */ 53 Config5 = 0x56, /* Configuration Register 5 */ 54 Timerint = 0x58, /* Timer Interrupt */ 55 Mulint = 0x5C, /* Multiple Interrupt Select */ 56 Phyar = 0x60, /* PHY Access */ 57 Tbicsr0 = 0x64, /* TBI Control and Status */ 58 Tbianar = 0x68, /* TBI Auto-Negotiation Advertisment */ 59 Tbilpar = 0x6A, /* TBI Auto-Negotiation Link Partner */ 60 Phystatus = 0x6C, /* PHY Status */ 61 62 Rms = 0xDA, /* Receive Packet Maximum Size */ 63 Cplusc = 0xE0, /* C+ Command */ 64 Rdsar = 0xE4, /* Receive Descriptor Start Address */ 65 Mtps = 0xEC, /* Max. Transmit Packet Size */ 66 }; 67 68 enum { /* Dtccr */ 69 Cmd = 0x00000008, /* Command */ 70 }; 71 72 enum { /* Cr */ 73 Te = 0x04, /* Transmitter Enable */ 74 Re = 0x08, /* Receiver Enable */ 75 Rst = 0x10, /* Software Reset */ 76 }; 77 78 enum { /* Tppoll */ 79 Fswint = 0x01, /* Forced Software Interrupt */ 80 Npq = 0x40, /* Normal Priority Queue polling */ 81 Hpq = 0x80, /* High Priority Queue polling */ 82 }; 83 84 enum { /* Imr/Isr */ 85 Rok = 0x0001, /* Receive OK */ 86 Rer = 0x0002, /* Receive Error */ 87 Tok = 0x0004, /* Transmit OK */ 88 Ter = 0x0008, /* Transmit Error */ 89 Rdu = 0x0010, /* Receive Descriptor Unavailable */ 90 Punlc = 0x0020, /* Packet Underrun or Link Change */ 91 Fovw = 0x0040, /* Receive FIFO Overflow */ 92 Tdu = 0x0080, /* Transmit Descriptor Unavailable */ 93 Swint = 0x0100, /* Software Interrupt */ 94 Timeout = 0x4000, /* Timer */ 95 Serr = 0x8000, /* System Error */ 96 }; 97 98 enum { /* Tcr */ 99 MtxdmaSHIFT = 8, /* Max. DMA Burst Size */ 100 MtxdmaMASK = 0x00000700, 101 Mtxdmaunlimited = 0x00000700, 102 Acrc = 0x00010000, /* Append CRC (not) */ 103 Lbk0 = 0x00020000, /* Loopback Test 0 */ 104 Lbk1 = 0x00040000, /* Loopback Test 1 */ 105 Ifg2 = 0x00080000, /* Interframe Gap 2 */ 106 HwveridSHIFT = 23, /* Hardware Version ID */ 107 HwveridMASK = 0x7C800000, 108 Macv01 = 0x00000000, /* RTL8169 */ 109 Macv02 = 0x00800000, /* RTL8169S/8110S */ 110 Macv03 = 0x04000000, /* RTL8169S/8110S */ 111 Macv04 = 0x10000000, /* RTL8169SB/8110SB */ 112 Macv05 = 0x18000000, /* RTL8169SC/8110SC */ 113 Macv11 = 0x30000000, /* RTL8168B/8111B */ 114 Macv12 = 0x38000000, /* RTL8169B/8111B */ 115 Macv13 = 0x34000000, /* RTL8101E */ 116 Macv14 = 0x30800000, /* RTL8100E */ 117 Macv15 = 0x38800000, /* RTL8100E */ 118 Ifg0 = 0x01000000, /* Interframe Gap 0 */ 119 Ifg1 = 0x02000000, /* Interframe Gap 1 */ 120 }; 121 122 enum { /* Rcr */ 123 Aap = 0x00000001, /* Accept All Packets */ 124 Apm = 0x00000002, /* Accept Physical Match */ 125 Am = 0x00000004, /* Accept Multicast */ 126 Ab = 0x00000008, /* Accept Broadcast */ 127 Ar = 0x00000010, /* Accept Runt */ 128 Aer = 0x00000020, /* Accept Error */ 129 Sel9356 = 0x00000040, /* 9356 EEPROM used */ 130 MrxdmaSHIFT = 8, /* Max. DMA Burst Size */ 131 MrxdmaMASK = 0x00000700, 132 Mrxdmaunlimited = 0x00000700, 133 RxfthSHIFT = 13, /* Receive Buffer Length */ 134 RxfthMASK = 0x0000E000, 135 Rxfth256 = 0x00008000, 136 Rxfthnone = 0x0000E000, 137 Rer8 = 0x00010000, /* Accept Error Packets > 8 bytes */ 138 MulERINT = 0x01000000, /* Multiple Early Interrupt Select */ 139 }; 140 141 enum { /* Cr9346 */ 142 Eedo = 0x01, /* */ 143 Eedi = 0x02, /* */ 144 Eesk = 0x04, /* */ 145 Eecs = 0x08, /* */ 146 Eem0 = 0x40, /* Operating Mode */ 147 Eem1 = 0x80, 148 }; 149 150 enum { /* Phyar */ 151 DataMASK = 0x0000FFFF, /* 16-bit GMII/MII Register Data */ 152 DataSHIFT = 0, 153 RegaddrMASK = 0x001F0000, /* 5-bit GMII/MII Register Address */ 154 RegaddrSHIFT = 16, 155 Flag = 0x80000000, /* */ 156 }; 157 158 enum { /* Phystatus */ 159 Fd = 0x01, /* Full Duplex */ 160 Linksts = 0x02, /* Link Status */ 161 Speed10 = 0x04, /* */ 162 Speed100 = 0x08, /* */ 163 Speed1000 = 0x10, /* */ 164 Rxflow = 0x20, /* */ 165 Txflow = 0x40, /* */ 166 Entbi = 0x80, /* */ 167 }; 168 169 enum { /* Cplusc */ 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, /* Large Send */ 192 }; 193 194 enum { /* Receive Descriptor control */ 195 RxflMASK = 0x00003FFF, /* Receive Frame Length */ 196 RxflSHIFT = 0, 197 Tcpf = 0x00004000, /* TCP Checksum Failure */ 198 Udpf = 0x00008000, /* UDP Checksum Failure */ 199 Ipf = 0x00010000, /* IP Checksum Failure */ 200 Pid0 = 0x00020000, /* Protocol ID0 */ 201 Pid1 = 0x00040000, /* Protocol ID1 */ 202 Crce = 0x00080000, /* CRC Error */ 203 Runt = 0x00100000, /* Runt Packet */ 204 Res = 0x00200000, /* Receive Error Summary */ 205 Rwt = 0x00400000, /* Receive Watchdog Timer Expired */ 206 Fovf = 0x00800000, /* FIFO Overflow */ 207 Bovf = 0x01000000, /* Buffer Overflow */ 208 Bar = 0x02000000, /* Broadcast Address Received */ 209 Pam = 0x04000000, /* Physical Address Matched */ 210 Mar = 0x08000000, /* Multicast Address Received */ 211 }; 212 213 enum { /* General Descriptor control */ 214 Ls = 0x10000000, /* Last Segment Descriptor */ 215 Fs = 0x20000000, /* First Segment Descriptor */ 216 Eor = 0x40000000, /* End of Descriptor Ring */ 217 Own = 0x80000000, /* Ownership */ 218 }; 219 220 /* 221 */ 222 enum { /* Ring sizes (<= 1024) */ 223 Ntd = 8, /* Transmit Ring */ 224 Nrd = 32, /* Receive Ring */ 225 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 ? */ 248 Rtl8169c = (0x0116<<16)|0x16EC, /* RTL8169C+ (USR997902) */ 249 Rtl8169sc = (0x8167<<16)|0x10EC, /* RTL8169SC */ 250 Rtl8168b = (0x8168<<16)|0x10EC, /* RTL8168B */ 251 Rtl8169 = (0x8169<<16)|0x10EC, /* RTL8169 */ 252 }; 253 254 typedef struct Ctlr Ctlr; 255 typedef struct Ctlr { 256 int port; 257 Pcidev* pcidev; 258 Ctlr* next; 259 int active; 260 261 void* nic; 262 263 QLock alock; /* attach */ 264 Lock ilock; /* init */ 265 int init; /* */ 266 267 int pciv; /* */ 268 int macv; /* MAC version */ 269 int phyv; /* PHY version */ 270 271 Mii* mii; 272 273 Lock tlock; /* transmit */ 274 D* td; /* descriptor ring */ 275 Block** tb; /* transmit buffers */ 276 int ntd; 277 278 int tdh; /* head - producer index (host) */ 279 int tdt; /* tail - consumer index (NIC) */ 280 int ntdfree; 281 int ntq; 282 283 int mtps; /* Max. Transmit Packet Size */ 284 285 Lock rlock; /* receive */ 286 D* rd; /* descriptor ring */ 287 void** rb; /* receive buffers */ 288 int nrd; 289 290 int rdh; /* head - producer index (NIC) */ 291 int rdt; /* tail - consumer index (host) */ 292 int nrdfree; 293 294 int rcr; /* receive configuration register */ 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 ierrs; 304 uint rer; 305 uint rdu; 306 uint punlc; 307 uint fovw; 308 } Ctlr; 309 310 static Ctlr* rtl8169ctlrhead; 311 static Ctlr* rtl8169ctlrtail; 312 313 #define csr8r(c, r) (inb((c)->port+(r))) 314 #define csr16r(c, r) (ins((c)->port+(r))) 315 #define csr32r(c, r) (inl((c)->port+(r))) 316 #define csr8w(c, r, b) (outb((c)->port+(r), (int)(b))) 317 #define csr16w(c, r, w) (outs((c)->port+(r), (ushort)(w))) 318 #define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l))) 319 320 static int 321 rtl8169miimir(Mii* mii, int pa, int ra) 322 { 323 uint r; 324 int timeo; 325 Ctlr *ctlr; 326 327 if(pa != 1) 328 return -1; 329 ctlr = mii->ctlr; 330 331 r = (ra<<16) & RegaddrMASK; 332 csr32w(ctlr, Phyar, r); 333 delay(1); 334 for(timeo = 0; timeo < 2000; timeo++){ 335 if((r = csr32r(ctlr, Phyar)) & Flag) 336 break; 337 microdelay(100); 338 } 339 if(!(r & Flag)) 340 return -1; 341 342 return (r & DataMASK)>>DataSHIFT; 343 } 344 345 static int 346 rtl8169miimiw(Mii* mii, int pa, int ra, int data) 347 { 348 uint r; 349 int timeo; 350 Ctlr *ctlr; 351 352 if(pa != 1) 353 return -1; 354 ctlr = mii->ctlr; 355 356 r = Flag|((ra<<16) & RegaddrMASK)|((data<<DataSHIFT) & DataMASK); 357 csr32w(ctlr, Phyar, r); 358 delay(1); 359 for(timeo = 0; timeo < 2000; timeo++){ 360 if(!((r = csr32r(ctlr, Phyar)) & Flag)) 361 break; 362 microdelay(100); 363 } 364 if(r & Flag) 365 return -1; 366 367 return 0; 368 } 369 370 static int 371 rtl8169mii(Ctlr* ctlr) 372 { 373 MiiPhy *phy; 374 375 /* 376 * Link management. 377 */ 378 if((ctlr->mii = malloc(sizeof(Mii))) == nil) 379 return -1; 380 ctlr->mii->mir = rtl8169miimir; 381 ctlr->mii->miw = rtl8169miimiw; 382 ctlr->mii->ctlr = ctlr; 383 384 /* 385 * Get rev number out of Phyidr2 so can config properly. 386 * There's probably more special stuff for Macv0[234] needed here. 387 */ 388 ctlr->phyv = rtl8169miimir(ctlr->mii, 1, Phyidr2) & 0x0F; 389 if(ctlr->macv == Macv02){ 390 csr8w(ctlr, 0x82, 1); /* magic */ 391 rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000); /* magic */ 392 } 393 394 if(mii(ctlr->mii, (1<<1)) == 0 || (phy = ctlr->mii->curphy) == nil){ 395 free(ctlr->mii); 396 ctlr->mii = nil; 397 return -1; 398 } 399 print("oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n", 400 phy->oui, phy->phyno, ctlr->macv, ctlr->phyv); 401 402 miiane(ctlr->mii, ~0, ~0, ~0); 403 404 return 0; 405 } 406 407 static void 408 rtl8169halt(Ctlr* ctlr) 409 { 410 csr8w(ctlr, Cr, 0); 411 csr16w(ctlr, Imr, 0); 412 csr16w(ctlr, Isr, ~0); 413 } 414 415 static int 416 rtl8169reset(Ctlr* ctlr) 417 { 418 u32int r; 419 int timeo; 420 421 /* 422 * Soft reset the controller. 423 */ 424 csr8w(ctlr, Cr, Rst); 425 for(r = timeo = 0; timeo < 1000; timeo++){ 426 r = csr8r(ctlr, Cr); 427 if(!(r & Rst)) 428 break; 429 delay(1); 430 } 431 rtl8169halt(ctlr); 432 433 if(r & Rst) 434 return -1; 435 return 0; 436 } 437 438 static void 439 rtl8169detach(Ether* edev) 440 { 441 rtl8169reset(edev->ctlr); 442 } 443 444 static void 445 rtl8169replenish(Ctlr* ctlr) 446 { 447 D *d; 448 int rdt; 449 void *bp; 450 451 rdt = ctlr->rdt; 452 while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){ 453 d = &ctlr->rd[rdt]; 454 if(ctlr->rb[rdt] == nil){ 455 /* 456 * simple allocation for now 457 */ 458 bp = mallocalign(Mps, 8, 0, 0); 459 ctlr->rb[rdt] = bp; 460 d->addrlo = PCIWADDR(bp); 461 d->addrhi = 0; 462 } 463 coherence(); 464 d->control |= Own|Mps; 465 rdt = NEXT(rdt, ctlr->nrd); 466 ctlr->nrdfree++; 467 } 468 ctlr->rdt = rdt; 469 } 470 471 static int 472 rtl8169init(Ether* edev) 473 { 474 u32int r; 475 Ctlr *ctlr; 476 u8int cplusc; 477 478 ctlr = edev->ctlr; 479 ilock(&ctlr->ilock); 480 481 rtl8169halt(ctlr); 482 483 /* 484 * MAC Address. 485 * Must put chip into config register write enable mode. 486 */ 487 csr8w(ctlr, Cr9346, Eem1|Eem0); 488 r = (edev->ea[3]<<24)|(edev->ea[2]<<16)|(edev->ea[1]<<8)|edev->ea[0]; 489 csr32w(ctlr, Idr0, r); 490 r = (edev->ea[5]<<8)|edev->ea[4]; 491 csr32w(ctlr, Idr0+4, r); 492 493 /* 494 * Transmitter. 495 */ 496 memset(ctlr->td, 0, sizeof(D)*ctlr->ntd); 497 ctlr->tdh = ctlr->tdt = 0; 498 ctlr->td[ctlr->ntd-1].control = Eor; 499 500 /* 501 * Receiver. 502 * Need to do something here about the multicast filter. 503 */ 504 memset(ctlr->rd, 0, sizeof(D)*ctlr->nrd); 505 ctlr->rdh = ctlr->rdt = 0; 506 ctlr->rd[ctlr->nrd-1].control = Eor; 507 rtl8169replenish(ctlr); 508 ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Apm; 509 510 /* 511 * Mtps is in units of 128 except for the RTL8169 512 * where is is 32. If using jumbo frames should be 513 * set to 0x3F. 514 * Setting Mulrw in Cplusc disables the Tx/Rx DMA burst 515 * settings in Tcr/Rcr; the (1<<14) is magic. 516 */ 517 ctlr->mtps = HOWMANY(Mps, 128); 518 cplusc = csr16r(ctlr, Cplusc) & ~(1<<14); 519 cplusc |= Rxchksum|Mulrw; 520 switch(ctlr->macv){ 521 default: 522 return -1; 523 case Macv01: 524 ctlr->mtps = HOWMANY(Mps, 32); 525 break; 526 case Macv02: 527 case Macv03: 528 cplusc |= (1<<14); /* magic */ 529 break; 530 case Macv05: 531 /* 532 * This is interpreted from clearly bogus code 533 * in the manufacturer-supplied driver, it could 534 * be wrong. Untested. 535 */ 536 r = csr8r(ctlr, Config2) & 0x07; 537 if(r == 0x01) /* 66MHz PCI */ 538 csr32w(ctlr, 0x7C, 0x0007FFFF); /* magic */ 539 else 540 csr32w(ctlr, 0x7C, 0x0007FF00); /* magic */ 541 pciclrmwi(ctlr->pcidev); 542 break; 543 case Macv13: 544 /* 545 * This is interpreted from clearly bogus code 546 * in the manufacturer-supplied driver, it could 547 * be wrong. Untested. 548 */ 549 pcicfgw8(ctlr->pcidev, 0x68, 0x00); /* magic */ 550 pcicfgw8(ctlr->pcidev, 0x69, 0x08); /* magic */ 551 break; 552 case Macv04: 553 case Macv11: 554 case Macv12: 555 case Macv14: 556 case Macv15: 557 break; 558 } 559 560 /* 561 * Enable receiver/transmitter. 562 * Need to do this first or some of the settings below 563 * won't take. 564 */ 565 switch(ctlr->pciv){ 566 default: 567 csr8w(ctlr, Cr, Te|Re); 568 csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited); 569 csr32w(ctlr, Rcr, ctlr->rcr); 570 case Rtl8169sc: 571 case Rtl8168b: 572 break; 573 } 574 575 /* 576 * Interrupts. 577 * Disable Tdu|Tok for now, the transmit routine will tidy. 578 * Tdu means the NIC ran out of descriptors to send, so it 579 * doesn't really need to ever be on. 580 */ 581 csr32w(ctlr, Timerint, 0); 582 csr16w(ctlr, Imr, Serr|Timeout|Fovw|Punlc|Rdu|Ter|Rer|Rok); 583 584 /* 585 * Clear missed-packet counter; 586 * initial early transmit threshold value; 587 * set the descriptor ring base addresses; 588 * set the maximum receive packet size; 589 * no early-receive interrupts. 590 */ 591 csr32w(ctlr, Mpc, 0); 592 csr8w(ctlr, Mtps, ctlr->mtps); 593 csr32w(ctlr, Tnpds+4, 0); 594 csr32w(ctlr, Tnpds, PCIWADDR(ctlr->td)); 595 csr32w(ctlr, Rdsar+4, 0); 596 csr32w(ctlr, Rdsar, PCIWADDR(ctlr->rd)); 597 csr16w(ctlr, Rms, Mps); 598 r = csr16r(ctlr, Mulint) & 0xF000; 599 csr16w(ctlr, Mulint, r); 600 csr16w(ctlr, Cplusc, cplusc); 601 602 /* 603 * Set configuration. 604 */ 605 switch(ctlr->pciv){ 606 default: 607 break; 608 case Rtl8169sc: 609 csr16w(ctlr, 0xE2, 0); /* magic */ 610 csr8w(ctlr, Cr, Te|Re); 611 csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited); 612 csr32w(ctlr, Rcr, ctlr->rcr); 613 break; 614 case Rtl8168b: 615 case Rtl8169c: 616 csr16w(ctlr, 0xE2, 0); /* magic */ 617 csr16w(ctlr, Cplusc, 0x2000); /* magic */ 618 csr8w(ctlr, Cr, Te|Re); 619 csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited); 620 csr32w(ctlr, Rcr, ctlr->rcr); 621 csr16w(ctlr, Rms, 0x0800); 622 csr8w(ctlr, Mtps, 0x3F); 623 break; 624 } 625 626 csr8w(ctlr, Cr9346, 0); 627 628 iunlock(&ctlr->ilock); 629 630 // rtl8169mii(ctlr); 631 632 return 0; 633 } 634 635 static void 636 rtl8169attach(Ether* edev) 637 { 638 int timeo; 639 Ctlr *ctlr; 640 641 ctlr = edev->ctlr; 642 qlock(&ctlr->alock); 643 if(ctlr->init == 0){ 644 /* 645 * Handle allocation/init errors here. 646 */ 647 ctlr->td = xspanalloc(sizeof(D)*Ntd, 256, 0); 648 ctlr->tb = malloc(Ntd*sizeof(Block*)); 649 ctlr->ntd = Ntd; 650 ctlr->rd = xspanalloc(sizeof(D)*Nrd, 256, 0); 651 ctlr->rb = malloc(Nrd*sizeof(Block*)); 652 ctlr->nrd = Nrd; 653 ctlr->dtcc = xspanalloc(sizeof(Dtcc), 64, 0); 654 rtl8169init(edev); 655 ctlr->init = 1; 656 } 657 qunlock(&ctlr->alock); 658 659 for(timeo = 0; timeo < 3500; timeo++){ 660 if(miistatus(ctlr->mii) == 0) 661 break; 662 delay(10); 663 } 664 } 665 666 static void 667 rtl8169transmit(Ether* edev) 668 { 669 D *d; 670 Block *bp; 671 Ctlr *ctlr; 672 int control, x; 673 RingBuf *tb; 674 675 ctlr = edev->ctlr; 676 677 ilock(&ctlr->tlock); 678 for(x = ctlr->tdh; ctlr->ntq > 0; x = NEXT(x, ctlr->ntd)){ 679 d = &ctlr->td[x]; 680 if((control = d->control) & Own) 681 break; 682 683 /* 684 * Check errors and log here. 685 */ 686 USED(control); 687 688 /* 689 * Free it up. 690 * Need to clean the descriptor here? Not really. 691 * Simple freeb for now (no chain and freeblist). 692 * Use ntq count for now. 693 */ 694 freeb(ctlr->tb[x]); 695 ctlr->tb[x] = nil; 696 d->control &= Eor; 697 698 ctlr->ntq--; 699 } 700 ctlr->tdh = x; 701 702 x = ctlr->tdt; 703 while(ctlr->ntq < (ctlr->ntd-1)){ 704 tb = &edev->tb[edev->ti]; 705 if(tb->owner != Interface) 706 break; 707 708 bp = allocb(tb->len); 709 memmove(bp->wp, tb->pkt, tb->len); 710 memmove(bp->wp+Eaddrlen, edev->ea, Eaddrlen); 711 bp->wp += tb->len; 712 713 tb->owner = Host; 714 edev->ti = NEXT(edev->ti, edev->ntb); 715 716 d = &ctlr->td[x]; 717 d->addrlo = PCIWADDR(bp->rp); 718 d->addrhi = 0; 719 ctlr->tb[x] = bp; 720 coherence(); 721 d->control |= Own|Fs|Ls|((BLEN(bp)<<TxflSHIFT) & TxflMASK); 722 723 x = NEXT(x, ctlr->ntd); 724 ctlr->ntq++; 725 } 726 if(x != ctlr->tdt){ 727 ctlr->tdt = x; 728 csr8w(ctlr, Tppoll, Npq); 729 } 730 else if(ctlr->ntq >= (ctlr->ntd-1)) 731 ctlr->txdu++; 732 733 iunlock(&ctlr->tlock); 734 } 735 736 static void 737 rtl8169receive(Ether* edev) 738 { 739 D *d; 740 int len, rdh; 741 Ctlr *ctlr; 742 u32int control; 743 RingBuf *ring; 744 745 ctlr = edev->ctlr; 746 747 rdh = ctlr->rdh; 748 for(;;){ 749 d = &ctlr->rd[rdh]; 750 751 if(d->control & Own) 752 break; 753 754 control = d->control; 755 if((control & (Fs|Ls|Res)) == (Fs|Ls)){ 756 len = ((control & RxflMASK)>>RxflSHIFT) - 4; 757 758 ring = &edev->rb[edev->ri]; 759 if(ring->owner == Interface){ 760 ring->owner = Host; 761 ring->len = len; 762 memmove(ring->pkt, ctlr->rb[rdh], len); 763 edev->ri = NEXT(edev->ri, edev->nrb); 764 } 765 } 766 else{ 767 /* 768 * Error stuff here. 769 print("control %#8.8ux\n", control); 770 */ 771 } 772 d->control &= Eor; 773 ctlr->nrdfree--; 774 rdh = NEXT(rdh, ctlr->nrd); 775 } 776 ctlr->rdh = rdh; 777 778 if(ctlr->nrdfree < ctlr->nrd/2) 779 rtl8169replenish(ctlr); 780 } 781 782 static void 783 rtl8169interrupt(Ureg*, void* arg) 784 { 785 Ctlr *ctlr; 786 Ether *edev; 787 u32int isr; 788 789 edev = arg; 790 ctlr = edev->ctlr; 791 792 while((isr = csr16r(ctlr, Isr)) != 0 && isr != 0xFFFF){ 793 csr16w(ctlr, Isr, isr); 794 if(isr & (Fovw|Punlc|Rdu|Rer|Rok)){ 795 rtl8169receive(edev); 796 if(!(isr & (Punlc|Rok))) 797 ctlr->ierrs++; 798 if(isr & Rer) 799 ctlr->rer++; 800 if(isr & Rdu) 801 ctlr->rdu++; 802 if(isr & Punlc) 803 ctlr->punlc++; 804 if(isr & Fovw) 805 ctlr->fovw++; 806 isr &= ~(Fovw|Rdu|Rer|Rok); 807 } 808 809 if(isr & (Tdu|Ter|Tok)){ 810 rtl8169transmit(edev); 811 isr &= ~(Tdu|Ter|Tok); 812 } 813 814 if(isr & Punlc){ 815 // rtl8169link(edev); 816 isr &= ~Punlc; 817 } 818 819 /* 820 * Some of the reserved bits get set sometimes... 821 */ 822 if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok)) 823 panic("rtl8169interrupt: imr %#4.4ux isr %#4.4ux\n", 824 csr16r(ctlr, Imr), isr); 825 } 826 } 827 828 static void 829 rtl8169pci(void) 830 { 831 Pcidev *p; 832 Ctlr *ctlr; 833 int i, port; 834 u32int bar; 835 836 p = nil; 837 while(p = pcimatch(p, 0, 0)){ 838 if(p->ccrb != 0x02 || p->ccru != 0) 839 continue; 840 841 switch(i = ((p->did<<16)|p->vid)){ 842 default: 843 continue; 844 case Rtl8100e: /* RTL810[01]E ? */ 845 case Rtl8169c: /* RTL8169C */ 846 case Rtl8169sc: /* RTL8169SC */ 847 case Rtl8168b: /* RTL8168B */ 848 case Rtl8169: /* RTL8169 */ 849 break; 850 case (0xC107<<16)|0x1259: /* Corega CG-LAPCIGT */ 851 i = Rtl8169; 852 break; 853 } 854 855 bar = p->mem[0].bar; 856 port = bar & ~0x01; 857 if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){ 858 print("rtl8169: port %#ux in use\n", port); 859 continue; 860 } 861 ctlr = malloc(sizeof(Ctlr)); 862 ctlr->port = port; 863 ctlr->pcidev = p; 864 ctlr->pciv = i; 865 866 if(pcigetpms(p) > 0){ 867 pcisetpms(p, 0); 868 869 for(i = 0; i < 6; i++) 870 pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar); 871 pcicfgw8(p, PciINTL, p->intl); 872 pcicfgw8(p, PciLTR, p->ltr); 873 pcicfgw8(p, PciCLS, p->cls); 874 pcicfgw16(p, PciPCR, p->pcr); 875 } 876 877 if(rtl8169reset(ctlr)){ 878 iofree(port); 879 free(ctlr); 880 continue; 881 } 882 883 /* 884 * Extract the chip hardware version, 885 * needed to configure each properly. 886 */ 887 ctlr->macv = csr32r(ctlr, Tcr) & HwveridMASK; 888 889 rtl8169mii(ctlr); 890 891 pcisetbme(p); 892 893 if(rtl8169ctlrhead != nil) 894 rtl8169ctlrtail->next = ctlr; 895 else 896 rtl8169ctlrhead = ctlr; 897 rtl8169ctlrtail = ctlr; 898 } 899 } 900 901 int 902 rtl8169pnp(Ether* edev) 903 { 904 u32int r; 905 Ctlr *ctlr; 906 907 if(rtl8169ctlrhead == nil) 908 rtl8169pci(); 909 910 /* 911 * Any adapter matches if no edev->port is supplied, 912 * otherwise the ports must match. 913 */ 914 for(ctlr = rtl8169ctlrhead; ctlr != nil; ctlr = ctlr->next){ 915 if(ctlr->active) 916 continue; 917 if(edev->port == 0 || edev->port == ctlr->port){ 918 ctlr->active = 1; 919 break; 920 } 921 } 922 if(ctlr == nil) 923 return -1; 924 925 edev->ctlr = ctlr; 926 edev->port = ctlr->port; 927 edev->irq = ctlr->pcidev->intl; 928 edev->tbdf = ctlr->pcidev->tbdf; 929 // edev->mbps = 100; 930 931 /* 932 * Pull the MAC address out of the chip. 933 */ 934 r = csr32r(ctlr, Idr0); 935 edev->ea[0] = r; 936 edev->ea[1] = r>>8; 937 edev->ea[2] = r>>16; 938 edev->ea[3] = r>>24; 939 r = csr32r(ctlr, Idr0+4); 940 edev->ea[4] = r; 941 edev->ea[5] = r>>8; 942 943 /* 944 * Linkage to the generic ethernet driver. 945 */ 946 edev->attach = rtl8169attach; 947 edev->transmit = rtl8169transmit; 948 edev->interrupt = rtl8169interrupt; 949 edev->detach = rtl8169detach; 950 // edev->ifstat = rtl8169ifstat; 951 // edev->ctl = nil; 952 // 953 // edev->arg = edev; 954 // edev->promiscuous = rtl8169promiscuous; 955 // edev->multicast = rtl8169multicast; 956 957 return 0; 958 } 959