1 /* 2 * National Semiconductor DP83820 3 * 10/100/1000 Mb/s Ethernet Network Interface Controller 4 * (Gig-NIC). 5 * Driver assumes little-endian and 32-bit host throughout. 6 */ 7 #include "u.h" 8 #include "../port/lib.h" 9 #include "mem.h" 10 #include "dat.h" 11 #include "fns.h" 12 #include "io.h" 13 #include "../port/error.h" 14 #include "../port/netif.h" 15 16 #include "etherif.h" 17 #include "ethermii.h" 18 19 enum { /* Registers */ 20 Cr = 0x00, /* Command */ 21 Cfg = 0x04, /* Configuration and Media Status */ 22 Mear = 0x08, /* MII/EEPROM Access */ 23 Ptscr = 0x0C, /* PCI Test Control */ 24 Isr = 0x10, /* Interrupt Status */ 25 Imr = 0x14, /* Interrupt Mask */ 26 Ier = 0x18, /* Interrupt Enable */ 27 Ihr = 0x1C, /* Interrupt Holdoff */ 28 Txdp = 0x20, /* Transmit Descriptor Pointer */ 29 Txdphi = 0x24, /* Transmit Descriptor Pointer Hi */ 30 Txcfg = 0x28, /* Transmit Configuration */ 31 Gpior = 0x2C, /* General Purpose I/O Control */ 32 Rxdp = 0x30, /* Receive Descriptor Pointer */ 33 Rxdphi = 0x34, /* Receive Descriptor Pointer Hi */ 34 Rxcfg = 0x38, /* Receive Configuration */ 35 Pqcr = 0x3C, /* Priority Queueing Control */ 36 Wcsr = 0x40, /* Wake on LAN Control/Status */ 37 Pcr = 0x44, /* Pause Control/Status */ 38 Rfcr = 0x48, /* Receive Filter/Match Control */ 39 Rfdr = 0x4C, /* Receive Filter/Match Data */ 40 Brar = 0x50, /* Boot ROM Address */ 41 Brdr = 0x54, /* Boot ROM Data */ 42 Srr = 0x58, /* Silicon Revision */ 43 Mibc = 0x5C, /* MIB Control */ 44 Mibd = 0x60, /* MIB Data */ 45 Txdp1 = 0xA0, /* Txdp Priority 1 */ 46 Txdp2 = 0xA4, /* Txdp Priority 2 */ 47 Txdp3 = 0xA8, /* Txdp Priority 3 */ 48 Rxdp1 = 0xB0, /* Rxdp Priority 1 */ 49 Rxdp2 = 0xB4, /* Rxdp Priority 2 */ 50 Rxdp3 = 0xB8, /* Rxdp Priority 3 */ 51 Vrcr = 0xBC, /* VLAN/IP Receive Control */ 52 Vtcr = 0xC0, /* VLAN/IP Transmit Control */ 53 Vdr = 0xC4, /* VLAN Data */ 54 Ccsr = 0xCC, /* Clockrun Control/Status */ 55 Tbicr = 0xE0, /* TBI Control */ 56 Tbisr = 0xE4, /* TBI Status */ 57 Tanar = 0xE8, /* TBI ANAR */ 58 Tanlpar = 0xEC, /* TBI ANLPAR */ 59 Taner = 0xF0, /* TBI ANER */ 60 Tesr = 0xF4, /* TBI ESR */ 61 }; 62 63 enum { /* Cr */ 64 Txe = 0x00000001, /* Transmit Enable */ 65 Txd = 0x00000002, /* Transmit Disable */ 66 Rxe = 0x00000004, /* Receiver Enable */ 67 Rxd = 0x00000008, /* Receiver Disable */ 68 Txr = 0x00000010, /* Transmitter Reset */ 69 Rxr = 0x00000020, /* Receiver Reset */ 70 Swien = 0x00000080, /* Software Interrupt Enable */ 71 Rst = 0x00000100, /* Reset */ 72 TxpriSHFT = 9, /* Tx Priority Queue Select */ 73 TxpriMASK = 0x00001E00, 74 RxpriSHFT = 13, /* Rx Priority Queue Select */ 75 RxpriMASK = 0x0001E000, 76 }; 77 78 enum { /* Configuration and Media Status */ 79 Bem = 0x00000001, /* Big Endian Mode */ 80 Ext125 = 0x00000002, /* External 125MHz reference Select */ 81 Bromdis = 0x00000004, /* Disable Boot ROM interface */ 82 Pesel = 0x00000008, /* Parity Error Detection Action */ 83 Exd = 0x00000010, /* Excessive Deferral Abort */ 84 Pow = 0x00000020, /* Program Out of Window Timer */ 85 Sb = 0x00000040, /* Single Back-off */ 86 Reqalg = 0x00000080, /* PCI Bus Request Algorithm */ 87 Extstsen = 0x00000100, /* Extended Status Enable */ 88 Phydis = 0x00000200, /* Disable PHY */ 89 Phyrst = 0x00000400, /* Reset PHY */ 90 M64addren = 0x00000800, /* Master 64-bit Addressing Enable */ 91 Data64en = 0x00001000, /* 64-bit Data Enable */ 92 Pci64det = 0x00002000, /* PCI 64-bit Bus Detected */ 93 T64addren = 0x00004000, /* Target 64-bit Addressing Enable */ 94 Mwidis = 0x00008000, /* MWI Disable */ 95 Mrmdis = 0x00010000, /* MRM Disable */ 96 Tmrtest = 0x00020000, /* Timer Test Mode */ 97 Spdstsien = 0x00040000, /* PHY Spdsts Interrupt Enable */ 98 Lnkstsien = 0x00080000, /* PHY Lnksts Interrupt Enable */ 99 Dupstsien = 0x00100000, /* PHY Dupsts Interrupt Enable */ 100 Mode1000 = 0x00400000, /* 1000Mb/s Mode Control */ 101 Tbien = 0x01000000, /* Ten-Bit Interface Enable */ 102 Dupsts = 0x10000000, /* Full Duplex Status */ 103 Spdsts100 = 0x20000000, /* SPEED100 Input Pin Status */ 104 Spdsts1000 = 0x40000000, /* SPEED1000 Input Pin Status */ 105 Lnksts = 0x80000000, /* Link Status */ 106 }; 107 108 enum { /* MII/EEPROM Access */ 109 Eedi = 0x00000001, /* EEPROM Data In */ 110 Eedo = 0x00000002, /* EEPROM Data Out */ 111 Eeclk = 0x00000004, /* EEPROM Serial Clock */ 112 Eesel = 0x00000008, /* EEPROM Chip Select */ 113 Mdio = 0x00000010, /* MII Management Data */ 114 Mddir = 0x00000020, /* MII Management Direction */ 115 Mdc = 0x00000040, /* MII Management Clock */ 116 }; 117 118 enum { /* Interrupts */ 119 Rxok = 0x00000001, /* Rx OK */ 120 Rxdesc = 0x00000002, /* Rx Descriptor */ 121 Rxerr = 0x00000004, /* Rx Packet Error */ 122 Rxearly = 0x00000008, /* Rx Early Threshold */ 123 Rxidle = 0x00000010, /* Rx Idle */ 124 Rxorn = 0x00000020, /* Rx Overrun */ 125 Txok = 0x00000040, /* Tx Packet OK */ 126 Txdesc = 0x00000080, /* Tx Descriptor */ 127 Txerr = 0x00000100, /* Tx Packet Error */ 128 Txidle = 0x00000200, /* Tx Idle */ 129 Txurn = 0x00000400, /* Tx Underrun */ 130 Mib = 0x00000800, /* MIB Service */ 131 Swi = 0x00001000, /* Software Interrupt */ 132 Pme = 0x00002000, /* Power Management Event */ 133 Phy = 0x00004000, /* PHY Interrupt */ 134 Hibint = 0x00008000, /* High Bits Interrupt Set */ 135 Rxsovr = 0x00010000, /* Rx Status FIFO Overrun */ 136 Rtabt = 0x00020000, /* Received Target Abort */ 137 Rmabt = 0x00040000, /* Received Master Abort */ 138 Sserr = 0x00080000, /* Signalled System Error */ 139 Dperr = 0x00100000, /* Detected Parity Error */ 140 Rxrcmp = 0x00200000, /* Receive Reset Complete */ 141 Txrcmp = 0x00400000, /* Transmit Reset Complete */ 142 Rxdesc0 = 0x00800000, /* Rx Descriptor for Priority Queue 0 */ 143 Rxdesc1 = 0x01000000, /* Rx Descriptor for Priority Queue 1 */ 144 Rxdesc2 = 0x02000000, /* Rx Descriptor for Priority Queue 2 */ 145 Rxdesc3 = 0x04000000, /* Rx Descriptor for Priority Queue 3 */ 146 Txdesc0 = 0x08000000, /* Tx Descriptor for Priority Queue 0 */ 147 Txdesc1 = 0x10000000, /* Tx Descriptor for Priority Queue 1 */ 148 Txdesc2 = 0x20000000, /* Tx Descriptor for Priority Queue 2 */ 149 Txdesc3 = 0x40000000, /* Tx Descriptor for Priority Queue 3 */ 150 }; 151 152 enum { /* Interrupt Enable */ 153 Ien = 0x00000001, /* Interrupt Enable */ 154 }; 155 156 enum { /* Interrupt Holdoff */ 157 IhSHFT = 0, /* Interrupt Holdoff */ 158 IhMASK = 0x000000FF, 159 Ihctl = 0x00000100, /* Interrupt Holdoff Control */ 160 }; 161 162 enum { /* Transmit Configuration */ 163 TxdrthSHFT = 0, /* Tx Drain Threshold */ 164 TxdrthMASK = 0x000000FF, 165 FlthSHFT = 16, /* Tx Fill Threshold */ 166 FlthMASK = 0x0000FF00, 167 Brstdis = 0x00080000, /* 1000Mb/s Burst Disable */ 168 MxdmaSHFT = 20, /* Max Size per Tx DMA Burst */ 169 MxdmaMASK = 0x00700000, 170 Ecretryen = 0x00800000, /* Excessive Collision Retry Enable */ 171 Atp = 0x10000000, /* Automatic Transmit Padding */ 172 Mlb = 0x20000000, /* MAC Loopback */ 173 Hbi = 0x40000000, /* Heartbeat Ignore */ 174 Csi = 0x80000000, /* Carrier Sense Ignore */ 175 }; 176 177 enum { /* Receive Configuration */ 178 RxdrthSHFT = 1, /* Rx Drain Threshold */ 179 RxdrthMASK = 0x0000003E, 180 Airl = 0x04000000, /* Accept In-Range Length Errored */ 181 Alp = 0x08000000, /* Accept Long Packets */ 182 Rxfd = 0x10000000, /* Receive Full Duplex */ 183 Stripcrc = 0x20000000, /* Strip CRC */ 184 Arp = 0x40000000, /* Accept Runt Packets */ 185 Aep = 0x80000000, /* Accept Errored Packets */ 186 }; 187 188 enum { /* Priority Queueing Control */ 189 Txpqen = 0x00000001, /* Transmit Priority Queuing Enable */ 190 Txfairen = 0x00000002, /* Transmit Fairness Enable */ 191 RxpqenSHFT = 2, /* Receive Priority Queue Enable */ 192 RxpqenMASK = 0x0000000C, 193 }; 194 195 enum { /* Pause Control/Status */ 196 PscntSHFT = 0, /* Pause Counter Value */ 197 PscntMASK = 0x0000FFFF, 198 Pstx = 0x00020000, /* Transmit Pause Frame */ 199 PsffloSHFT = 18, /* Rx Data FIFO Lo Threshold */ 200 PsffloMASK = 0x000C0000, 201 PsffhiSHFT = 20, /* Rx Data FIFO Hi Threshold */ 202 PsffhiMASK = 0x00300000, 203 PsstloSHFT = 22, /* Rx Stat FIFO Hi Threshold */ 204 PsstloMASK = 0x00C00000, 205 PssthiSHFT = 24, /* Rx Stat FIFO Hi Threshold */ 206 PssthiMASK = 0x03000000, 207 Psrcvd = 0x08000000, /* Pause Frame Received */ 208 Psact = 0x10000000, /* Pause Active */ 209 Psda = 0x20000000, /* Pause on Destination Address */ 210 Psmcast = 0x40000000, /* Pause on Multicast */ 211 Psen = 0x80000000, /* Pause Enable */ 212 }; 213 214 enum { /* Receive Filter/Match Control */ 215 RfaddrSHFT = 0, /* Extended Register Address */ 216 RfaddrMASK = 0x000003FF, 217 Ulm = 0x00080000, /* U/L bit mask */ 218 Uhen = 0x00100000, /* Unicast Hash Enable */ 219 Mhen = 0x00200000, /* Multicast Hash Enable */ 220 Aarp = 0x00400000, /* Accept ARP Packets */ 221 ApatSHFT = 23, /* Accept on Pattern Match */ 222 ApatMASK = 0x07800000, 223 Apm = 0x08000000, /* Accept on Perfect Match */ 224 Aau = 0x10000000, /* Accept All Unicast */ 225 Aam = 0x20000000, /* Accept All Multicast */ 226 Aab = 0x40000000, /* Accept All Broadcast */ 227 Rfen = 0x80000000, /* Rx Filter Enable */ 228 }; 229 230 enum { /* Receive Filter/Match Data */ 231 RfdataSHFT = 0, /* Receive Filter Data */ 232 RfdataMASK = 0x0000FFFF, 233 BmaskSHFT = 16, /* Byte Mask */ 234 BmaskMASK = 0x00030000, 235 }; 236 237 enum { /* MIB Control */ 238 Wrn = 0x00000001, /* Warning Test Indicator */ 239 Frz = 0x00000002, /* Freeze All Counters */ 240 Aclr = 0x00000004, /* Clear All Counters */ 241 Mibs = 0x00000008, /* MIB Counter Strobe */ 242 }; 243 244 enum { /* MIB Data */ 245 Nmibd = 11, /* Number of MIB Data Registers */ 246 }; 247 248 enum { /* VLAN/IP Receive Control */ 249 Vtden = 0x00000001, /* VLAN Tag Detection Enable */ 250 Vtren = 0x00000002, /* VLAN Tag Removal Enable */ 251 Dvtf = 0x00000004, /* Discard VLAN Tagged Frames */ 252 Dutf = 0x00000008, /* Discard Untagged Frames */ 253 Ipen = 0x00000010, /* IP Checksum Enable */ 254 Ripe = 0x00000020, /* Reject IP Checksum Errors */ 255 Rtcpe = 0x00000040, /* Reject TCP Checksum Errors */ 256 Rudpe = 0x00000080, /* Reject UDP Checksum Errors */ 257 }; 258 259 enum { /* VLAN/IP Transmit Control */ 260 Vgti = 0x00000001, /* VLAN Global Tag Insertion */ 261 Vppti = 0x00000002, /* VLAN Per-Packet Tag Insertion */ 262 Gchk = 0x00000004, /* Global Checksum Generation */ 263 Ppchk = 0x00000008, /* Per-Packet Checksum Generation */ 264 }; 265 266 enum { /* VLAN Data */ 267 VtypeSHFT = 0, /* VLAN Type Field */ 268 VtypeMASK = 0x0000FFFF, 269 VtciSHFT = 16, /* VLAN Tag Control Information */ 270 VtciMASK = 0xFFFF0000, 271 }; 272 273 enum { /* Clockrun Control/Status */ 274 Clkrunen = 0x00000001, /* CLKRUN Enable */ 275 Pmeen = 0x00000100, /* PME Enable */ 276 Pmests = 0x00008000, /* PME Status */ 277 }; 278 279 typedef struct { 280 u32int link; /* Link to the next descriptor */ 281 u32int bufptr; /* pointer to data Buffer */ 282 int cmdsts; /* Command/Status */ 283 int extsts; /* optional Extended Status */ 284 285 Block* bp; /* Block containing bufptr */ 286 u32int unused; /* pad to 64-bit */ 287 } Desc; 288 289 enum { /* Common cmdsts bits */ 290 SizeMASK = 0x0000FFFF, /* Descriptor Byte Count */ 291 SizeSHFT = 0, 292 Ok = 0x08000000, /* Packet OK */ 293 Crc = 0x10000000, /* Suppress/Include CRC */ 294 Intr = 0x20000000, /* Interrupt on ownership transfer */ 295 More = 0x40000000, /* not last descriptor in a packet */ 296 Own = 0x80000000, /* Descriptor Ownership */ 297 }; 298 299 enum { /* Transmit cmdsts bits */ 300 CcntMASK = 0x000F0000, /* Collision Count */ 301 CcntSHFT = 16, 302 Ec = 0x00100000, /* Excessive Collisions */ 303 Owc = 0x00200000, /* Out of Window Collision */ 304 Ed = 0x00400000, /* Excessive Deferral */ 305 Td = 0x00800000, /* Transmit Deferred */ 306 Crs = 0x01000000, /* Carrier Sense Lost */ 307 Tfu = 0x02000000, /* Transmit FIFO Underrun */ 308 Txa = 0x04000000, /* Transmit Abort */ 309 }; 310 311 enum { /* Receive cmdsts bits */ 312 Irl = 0x00010000, /* In-Range Length Error */ 313 Lbp = 0x00020000, /* Loopback Packet */ 314 Fae = 0x00040000, /* Frame Alignment Error */ 315 Crce = 0x00080000, /* CRC Error */ 316 Ise = 0x00100000, /* Invalid Symbol Error */ 317 Runt = 0x00200000, /* Runt Packet Received */ 318 Long = 0x00400000, /* Too Long Packet Received */ 319 DestMASK = 0x01800000, /* Destination Class */ 320 DestSHFT = 23, 321 Rxo = 0x02000000, /* Receive Overrun */ 322 Rxa = 0x04000000, /* Receive Aborted */ 323 }; 324 325 enum { /* extsts bits */ 326 EvtciMASK = 0x0000FFFF, /* VLAN Tag Control Information */ 327 EvtciSHFT = 0, 328 Vpkt = 0x00010000, /* VLAN Packet */ 329 Ippkt = 0x00020000, /* IP Packet */ 330 Iperr = 0x00040000, /* IP Checksum Error */ 331 Tcppkt = 0x00080000, /* TCP Packet */ 332 Tcperr = 0x00100000, /* TCP Checksum Error */ 333 Udppkt = 0x00200000, /* UDP Packet */ 334 Udperr = 0x00400000, /* UDP Checksum Error */ 335 }; 336 337 enum { 338 Nrd = 256, 339 Nrb = 4*Nrd, 340 Rbsz = ROUNDUP(sizeof(Etherpkt)+8, 8), 341 Ntd = 64, 342 }; 343 344 typedef struct Ctlr Ctlr; 345 typedef struct Ctlr { 346 int port; 347 Pcidev* pcidev; 348 Ctlr* next; 349 int active; 350 int id; 351 352 int eepromsz; /* address size in bits */ 353 ushort* eeprom; 354 355 int* nic; 356 int cfg; 357 int imr; 358 359 QLock alock; /* attach */ 360 Lock ilock; /* init */ 361 void* alloc; /* base of per-Ctlr allocated data */ 362 363 Mii* mii; 364 365 Lock rdlock; /* receive */ 366 Desc* rd; 367 int nrd; 368 int nrb; 369 int rdx; 370 int rxcfg; 371 372 Lock tlock; /* transmit */ 373 Desc* td; 374 int ntd; 375 int tdh; 376 int tdt; 377 int ntq; 378 int txcfg; 379 380 int rxidle; 381 382 uint mibd[Nmibd]; 383 384 int ec; 385 int owc; 386 int ed; 387 int crs; 388 int tfu; 389 int txa; 390 } Ctlr; 391 392 #define csr32r(c, r) (*((c)->nic+((r)/4))) 393 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v)) 394 395 static Ctlr* dp83820ctlrhead; 396 static Ctlr* dp83820ctlrtail; 397 398 static Lock dp83820rblock; /* free receive Blocks */ 399 static Block* dp83820rbpool; 400 401 static char* dp83820mibs[Nmibd] = { 402 "RXErroredPkts", 403 "RXFCSErrors", 404 "RXMsdPktErrors", 405 "RXFAErrors", 406 "RXSymbolErrors", 407 "RXFrameToLong", 408 "RXIRLErrors", 409 "RXBadOpcodes", 410 "RXPauseFrames", 411 "TXPauseFrames", 412 "TXSQEErrors", 413 }; 414 415 static int 416 mdior(Ctlr* ctlr, int n) 417 { 418 int data, i, mear, r; 419 420 mear = csr32r(ctlr, Mear); 421 r = ~(Mdc|Mddir) & mear; 422 data = 0; 423 for(i = n-1; i >= 0; i--){ 424 if(csr32r(ctlr, Mear) & Mdio) 425 data |= (1<<i); 426 csr32w(ctlr, Mear, Mdc|r); 427 csr32w(ctlr, Mear, r); 428 } 429 csr32w(ctlr, Mear, mear); 430 431 return data; 432 } 433 434 static void 435 mdiow(Ctlr* ctlr, int bits, int n) 436 { 437 int i, mear, r; 438 439 mear = csr32r(ctlr, Mear); 440 r = Mddir|(~Mdc & mear); 441 for(i = n-1; i >= 0; i--){ 442 if(bits & (1<<i)) 443 r |= Mdio; 444 else 445 r &= ~Mdio; 446 csr32w(ctlr, Mear, r); 447 csr32w(ctlr, Mear, Mdc|r); 448 } 449 csr32w(ctlr, Mear, mear); 450 } 451 452 static int 453 dp83820miimir(Mii* mii, int pa, int ra) 454 { 455 int data; 456 Ctlr *ctlr; 457 458 ctlr = mii->ctlr; 459 460 /* 461 * MII Management Interface Read. 462 * 463 * Preamble; 464 * ST+OP+PA+RA; 465 * LT + 16 data bits. 466 */ 467 mdiow(ctlr, 0xFFFFFFFF, 32); 468 mdiow(ctlr, 0x1800|(pa<<5)|ra, 14); 469 data = mdior(ctlr, 18); 470 471 if(data & 0x10000) 472 return -1; 473 474 return data & 0xFFFF; 475 } 476 477 static int 478 dp83820miimiw(Mii* mii, int pa, int ra, int data) 479 { 480 Ctlr *ctlr; 481 482 ctlr = mii->ctlr; 483 484 /* 485 * MII Management Interface Write. 486 * 487 * Preamble; 488 * ST+OP+PA+RA+LT + 16 data bits; 489 * Z. 490 */ 491 mdiow(ctlr, 0xFFFFFFFF, 32); 492 data &= 0xFFFF; 493 data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16); 494 mdiow(ctlr, data, 32); 495 496 return 0; 497 } 498 499 static Block * 500 dp83820rballoc(Desc* desc) 501 { 502 Block *bp; 503 504 if(desc->bp == nil){ 505 ilock(&dp83820rblock); 506 if((bp = dp83820rbpool) == nil){ 507 iunlock(&dp83820rblock); 508 desc->bp = nil; 509 desc->cmdsts = Own; 510 return nil; 511 } 512 dp83820rbpool = bp->next; 513 bp->next = nil; 514 _xinc(&bp->ref); /* prevent bp from being freed */ 515 iunlock(&dp83820rblock); 516 517 desc->bufptr = PCIWADDR(bp->rp); 518 desc->bp = bp; 519 } 520 else{ 521 bp = desc->bp; 522 bp->rp = bp->lim - Rbsz; 523 bp->wp = bp->rp; 524 } 525 526 coherence(); 527 desc->cmdsts = Intr|Rbsz; 528 529 return bp; 530 } 531 532 static void 533 dp83820rbfree(Block *bp) 534 { 535 bp->rp = bp->lim - Rbsz; 536 bp->wp = bp->rp; 537 538 ilock(&dp83820rblock); 539 bp->next = dp83820rbpool; 540 dp83820rbpool = bp; 541 iunlock(&dp83820rblock); 542 } 543 544 static void 545 dp83820halt(Ctlr* ctlr) 546 { 547 int i, timeo; 548 549 ilock(&ctlr->ilock); 550 csr32w(ctlr, Imr, 0); 551 csr32w(ctlr, Ier, 0); 552 csr32w(ctlr, Cr, Rxd|Txd); 553 for(timeo = 0; timeo < 1000; timeo++){ 554 if(!(csr32r(ctlr, Cr) & (Rxe|Txe))) 555 break; 556 microdelay(1); 557 } 558 csr32w(ctlr, Mibc, Frz); 559 iunlock(&ctlr->ilock); 560 561 if(ctlr->rd != nil){ 562 for(i = 0; i < ctlr->nrd; i++){ 563 if(ctlr->rd[i].bp == nil) 564 continue; 565 freeb(ctlr->rd[i].bp); 566 ctlr->rd[i].bp = nil; 567 } 568 } 569 if(ctlr->td != nil){ 570 for(i = 0; i < ctlr->ntd; i++){ 571 if(ctlr->td[i].bp == nil) 572 continue; 573 freeb(ctlr->td[i].bp); 574 ctlr->td[i].bp = nil; 575 } 576 } 577 } 578 579 static void 580 dp83820cfg(Ctlr* ctlr) 581 { 582 int cfg; 583 584 /* 585 * Don't know how to deal with a TBI yet. 586 */ 587 if(ctlr->mii == nil) 588 return; 589 590 /* 591 * The polarity of these bits is at the mercy 592 * of the board designer. 593 * The correct answer for all speed and duplex questions 594 * should be to query the phy. 595 */ 596 cfg = csr32r(ctlr, Cfg); 597 if(!(cfg & Dupsts)){ 598 ctlr->rxcfg |= Rxfd; 599 ctlr->txcfg |= Csi|Hbi; 600 iprint("83820: full duplex, "); 601 } 602 else{ 603 ctlr->rxcfg &= ~Rxfd; 604 ctlr->txcfg &= ~(Csi|Hbi); 605 iprint("83820: half duplex, "); 606 } 607 csr32w(ctlr, Rxcfg, ctlr->rxcfg); 608 csr32w(ctlr, Txcfg, ctlr->txcfg); 609 610 switch(cfg & (Spdsts1000|Spdsts100)){ 611 case Spdsts1000: /* 100Mbps */ 612 default: /* 10Mbps */ 613 ctlr->cfg &= ~Mode1000; 614 if((cfg & (Spdsts1000|Spdsts100)) == Spdsts1000) 615 iprint("100Mb/s\n"); 616 else 617 iprint("10Mb/s\n"); 618 break; 619 case Spdsts100: /* 1Gbps */ 620 ctlr->cfg |= Mode1000; 621 iprint("1Gb/s\n"); 622 break; 623 } 624 csr32w(ctlr, Cfg, ctlr->cfg); 625 } 626 627 static void 628 dp83820init(Ether* edev) 629 { 630 int i; 631 Ctlr *ctlr; 632 Desc *desc; 633 uchar *alloc; 634 635 ctlr = edev->ctlr; 636 637 dp83820halt(ctlr); 638 639 /* 640 * Receiver 641 */ 642 alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 8); 643 ctlr->rd = (Desc*)alloc; 644 alloc += ctlr->nrd*sizeof(Desc); 645 memset(ctlr->rd, 0, ctlr->nrd*sizeof(Desc)); 646 ctlr->rdx = 0; 647 for(i = 0; i < ctlr->nrd; i++){ 648 desc = &ctlr->rd[i]; 649 desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]); 650 if(dp83820rballoc(desc) == nil) 651 continue; 652 } 653 csr32w(ctlr, Rxdphi, 0); 654 csr32w(ctlr, Rxdp, PCIWADDR(ctlr->rd)); 655 656 for(i = 0; i < Eaddrlen; i += 2){ 657 csr32w(ctlr, Rfcr, i); 658 csr32w(ctlr, Rfdr, (edev->ea[i+1]<<8)|edev->ea[i]); 659 } 660 csr32w(ctlr, Rfcr, Rfen|Aab|Aam|Apm); 661 662 ctlr->rxcfg = Stripcrc|(((2*(ETHERMINTU+4))/8)<<RxdrthSHFT); 663 ctlr->imr |= Rxorn|Rxidle|Rxearly|Rxdesc|Rxok; 664 665 /* 666 * Transmitter. 667 */ 668 ctlr->td = (Desc*)alloc; 669 memset(ctlr->td, 0, ctlr->ntd*sizeof(Desc)); 670 ctlr->tdh = ctlr->tdt = ctlr->ntq = 0; 671 for(i = 0; i < ctlr->ntd; i++){ 672 desc = &ctlr->td[i]; 673 desc->link = PCIWADDR(&ctlr->td[NEXT(i, ctlr->ntd)]); 674 } 675 csr32w(ctlr, Txdphi, 0); 676 csr32w(ctlr, Txdp, PCIWADDR(ctlr->td)); 677 678 ctlr->txcfg = Atp|(((2*(ETHERMINTU+4))/32)<<FlthSHFT)|((4096/32)<<TxdrthSHFT); 679 ctlr->imr |= Txurn|Txidle|Txdesc|Txok; 680 681 ilock(&ctlr->ilock); 682 683 dp83820cfg(ctlr); 684 685 csr32w(ctlr, Mibc, Aclr); 686 ctlr->imr |= Mib; 687 688 csr32w(ctlr, Imr, ctlr->imr); 689 690 /* try coalescing adjacent interrupts; use hold-off interval of 100µs */ 691 csr32w(ctlr, Ihr, Ihctl|(1<<IhSHFT)); 692 693 csr32w(ctlr, Ier, Ien); 694 csr32w(ctlr, Cr, Rxe|Txe); 695 696 iunlock(&ctlr->ilock); 697 } 698 699 static void 700 dp83820attach(Ether* edev) 701 { 702 Block *bp; 703 Ctlr *ctlr; 704 705 ctlr = edev->ctlr; 706 qlock(&ctlr->alock); 707 if(ctlr->alloc != nil){ 708 qunlock(&ctlr->alock); 709 return; 710 } 711 712 if(waserror()){ 713 if(ctlr->mii != nil){ 714 free(ctlr->mii); 715 ctlr->mii = nil; 716 } 717 if(ctlr->alloc != nil){ 718 free(ctlr->alloc); 719 ctlr->alloc = nil; 720 } 721 qunlock(&ctlr->alock); 722 nexterror(); 723 } 724 725 if(!(ctlr->cfg & Tbien)){ 726 if((ctlr->mii = malloc(sizeof(Mii))) == nil) 727 error(Enomem); 728 ctlr->mii->ctlr = ctlr; 729 ctlr->mii->mir = dp83820miimir; 730 ctlr->mii->miw = dp83820miimiw; 731 if(mii(ctlr->mii, ~0) == 0) 732 error("no PHY"); 733 ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien; 734 ctlr->imr |= Phy; 735 } 736 737 ctlr->nrd = Nrd; 738 ctlr->nrb = Nrb; 739 ctlr->ntd = Ntd; 740 ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0); 741 if(ctlr->alloc == nil) 742 error(Enomem); 743 744 for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){ 745 if((bp = allocb(Rbsz)) == nil) 746 break; 747 bp->free = dp83820rbfree; 748 dp83820rbfree(bp); 749 } 750 751 dp83820init(edev); 752 753 qunlock(&ctlr->alock); 754 poperror(); 755 } 756 757 static void 758 dp83820transmit(Ether* edev) 759 { 760 Block *bp; 761 Ctlr *ctlr; 762 Desc *desc; 763 int cmdsts, r, x; 764 765 ctlr = edev->ctlr; 766 767 ilock(&ctlr->tlock); 768 769 bp = nil; 770 for(x = ctlr->tdh; ctlr->ntq; x = NEXT(x, ctlr->ntd)){ 771 desc = &ctlr->td[x]; 772 if((cmdsts = desc->cmdsts) & Own) 773 break; 774 if(!(cmdsts & Ok)){ 775 if(cmdsts & Ec) 776 ctlr->ec++; 777 if(cmdsts & Owc) 778 ctlr->owc++; 779 if(cmdsts & Ed) 780 ctlr->ed++; 781 if(cmdsts & Crs) 782 ctlr->crs++; 783 if(cmdsts & Tfu) 784 ctlr->tfu++; 785 if(cmdsts & Txa) 786 ctlr->txa++; 787 edev->oerrs++; 788 } 789 desc->bp->next = bp; 790 bp = desc->bp; 791 desc->bp = nil; 792 793 ctlr->ntq--; 794 } 795 ctlr->tdh = x; 796 if(bp != nil) 797 freeblist(bp); 798 799 x = ctlr->tdt; 800 while(ctlr->ntq < (ctlr->ntd-1)){ 801 if((bp = qget(edev->oq)) == nil) 802 break; 803 804 desc = &ctlr->td[x]; 805 desc->bufptr = PCIWADDR(bp->rp); 806 desc->bp = bp; 807 ctlr->ntq++; 808 coherence(); 809 desc->cmdsts = Own|Intr|BLEN(bp); 810 811 x = NEXT(x, ctlr->ntd); 812 } 813 if(x != ctlr->tdt){ 814 ctlr->tdt = x; 815 r = csr32r(ctlr, Cr); 816 csr32w(ctlr, Cr, Txe|r); 817 } 818 819 iunlock(&ctlr->tlock); 820 } 821 822 static void 823 dp83820interrupt(Ureg*, void* arg) 824 { 825 Block *bp; 826 Ctlr *ctlr; 827 Desc *desc; 828 Ether *edev; 829 int cmdsts, i, isr, r, x; 830 831 edev = arg; 832 ctlr = edev->ctlr; 833 834 for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){ 835 if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){ 836 x = ctlr->rdx; 837 desc = &ctlr->rd[x]; 838 while((cmdsts = desc->cmdsts) & Own){ 839 if((cmdsts & Ok) && desc->bp != nil){ 840 bp = desc->bp; 841 desc->bp = nil; 842 bp->wp += cmdsts & SizeMASK; 843 etheriq(edev, bp, 1); 844 } 845 else if(0 && !(cmdsts & Ok)){ 846 iprint("dp83820: rx %8.8uX:", cmdsts); 847 bp = desc->bp; 848 for(i = 0; i < 20; i++) 849 iprint(" %2.2uX", bp->rp[i]); 850 iprint("\n"); 851 } 852 dp83820rballoc(desc); 853 854 x = NEXT(x, ctlr->nrd); 855 desc = &ctlr->rd[x]; 856 } 857 ctlr->rdx = x; 858 859 if(isr & Rxidle){ 860 r = csr32r(ctlr, Cr); 861 csr32w(ctlr, Cr, Rxe|r); 862 ctlr->rxidle++; 863 } 864 865 isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok); 866 } 867 868 if(isr & Txurn){ 869 x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT; 870 r = (ctlr->txcfg & FlthMASK)>>FlthSHFT; 871 if(x < ((TxdrthMASK)>>TxdrthSHFT) 872 && x < (2048/32 - r)){ 873 ctlr->txcfg &= ~TxdrthMASK; 874 x++; 875 ctlr->txcfg |= x<<TxdrthSHFT; 876 csr32w(ctlr, Txcfg, ctlr->txcfg); 877 } 878 } 879 880 if(isr & (Txurn|Txidle|Txdesc|Txok)){ 881 dp83820transmit(edev); 882 isr &= ~(Txurn|Txidle|Txdesc|Txok); 883 } 884 885 if(isr & Mib){ 886 for(i = 0; i < Nmibd; i++){ 887 r = csr32r(ctlr, Mibd+(i*sizeof(int))); 888 ctlr->mibd[i] += r & 0xFFFF; 889 } 890 isr &= ~Mib; 891 } 892 893 if((isr & Phy) && ctlr->mii != nil){ 894 ctlr->mii->mir(ctlr->mii, 1, Bmsr); 895 print("phy: cfg %8.8uX bmsr %4.4uX\n", 896 csr32r(ctlr, Cfg), 897 ctlr->mii->mir(ctlr->mii, 1, Bmsr)); 898 dp83820cfg(ctlr); 899 isr &= ~Phy; 900 } 901 if(isr) 902 iprint("dp83820: isr %8.8uX\n", isr); 903 } 904 } 905 906 static long 907 dp83820ifstat(Ether* edev, void* a, long n, ulong offset) 908 { 909 char *p; 910 Ctlr *ctlr; 911 int i, l, r; 912 913 ctlr = edev->ctlr; 914 915 edev->crcs = ctlr->mibd[Mibd+(1*sizeof(int))]; 916 edev->frames = ctlr->mibd[Mibd+(3*sizeof(int))]; 917 edev->buffs = ctlr->mibd[Mibd+(5*sizeof(int))]; 918 edev->overflows = ctlr->mibd[Mibd+(2*sizeof(int))]; 919 920 if(n == 0) 921 return 0; 922 923 p = malloc(READSTR); 924 if(p == nil) 925 error(Enomem); 926 l = 0; 927 for(i = 0; i < Nmibd; i++){ 928 r = csr32r(ctlr, Mibd+(i*sizeof(int))); 929 ctlr->mibd[i] += r & 0xFFFF; 930 if(ctlr->mibd[i] != 0 && dp83820mibs[i] != nil) 931 l += snprint(p+l, READSTR-l, "%s: %ud %ud\n", 932 dp83820mibs[i], ctlr->mibd[i], r); 933 } 934 l += snprint(p+l, READSTR-l, "rxidle %d\n", ctlr->rxidle); 935 l += snprint(p+l, READSTR-l, "ec %d\n", ctlr->ec); 936 l += snprint(p+l, READSTR-l, "owc %d\n", ctlr->owc); 937 l += snprint(p+l, READSTR-l, "ed %d\n", ctlr->ed); 938 l += snprint(p+l, READSTR-l, "crs %d\n", ctlr->crs); 939 l += snprint(p+l, READSTR-l, "tfu %d\n", ctlr->tfu); 940 l += snprint(p+l, READSTR-l, "txa %d\n", ctlr->txa); 941 942 l += snprint(p+l, READSTR, "rom:"); 943 for(i = 0; i < 0x10; i++){ 944 if(i && ((i & 0x07) == 0)) 945 l += snprint(p+l, READSTR-l, "\n "); 946 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]); 947 } 948 l += snprint(p+l, READSTR-l, "\n"); 949 950 if(ctlr->mii != nil && ctlr->mii->curphy != nil){ 951 l += snprint(p+l, READSTR, "phy:"); 952 for(i = 0; i < NMiiPhyr; i++){ 953 if(i && ((i & 0x07) == 0)) 954 l += snprint(p+l, READSTR-l, "\n "); 955 r = miimir(ctlr->mii, i); 956 l += snprint(p+l, READSTR-l, " %4.4uX", r); 957 } 958 snprint(p+l, READSTR-l, "\n"); 959 } 960 961 n = readstr(offset, a, n, p); 962 free(p); 963 964 return n; 965 } 966 967 static void 968 dp83820promiscuous(void* arg, int on) 969 { 970 USED(arg, on); 971 } 972 973 /* multicast already on, don't need to do anything */ 974 static void 975 dp83820multicast(void*, uchar*, int) 976 { 977 } 978 979 static int 980 dp83820detach(Ctlr* ctlr) 981 { 982 /* 983 * Soft reset the controller. 984 */ 985 csr32w(ctlr, Cr, Rst); 986 delay(1); 987 while(csr32r(ctlr, Cr) & Rst) 988 delay(1); 989 return 0; 990 } 991 992 static void 993 dp83820shutdown(Ether* ether) 994 { 995 print("dp83820shutdown\n"); 996 dp83820detach(ether->ctlr); 997 } 998 999 static int 1000 atc93c46r(Ctlr* ctlr, int address) 1001 { 1002 int data, i, mear, r, size; 1003 1004 /* 1005 * Analog Technology, Inc. ATC93C46 1006 * or equivalent serial EEPROM. 1007 */ 1008 mear = csr32r(ctlr, Mear); 1009 mear &= ~(Eesel|Eeclk|Eedo|Eedi); 1010 r = Eesel|mear; 1011 1012 reread: 1013 csr32w(ctlr, Mear, r); 1014 data = 0x06; 1015 for(i = 3-1; i >= 0; i--){ 1016 if(data & (1<<i)) 1017 r |= Eedi; 1018 else 1019 r &= ~Eedi; 1020 csr32w(ctlr, Mear, r); 1021 csr32w(ctlr, Mear, Eeclk|r); 1022 microdelay(1); 1023 csr32w(ctlr, Mear, r); 1024 microdelay(1); 1025 } 1026 1027 /* 1028 * First time through must work out the EEPROM size. 1029 */ 1030 if((size = ctlr->eepromsz) == 0) 1031 size = 8; 1032 1033 for(size = size-1; size >= 0; size--){ 1034 if(address & (1<<size)) 1035 r |= Eedi; 1036 else 1037 r &= ~Eedi; 1038 csr32w(ctlr, Mear, r); 1039 microdelay(1); 1040 csr32w(ctlr, Mear, Eeclk|r); 1041 microdelay(1); 1042 csr32w(ctlr, Mear, r); 1043 microdelay(1); 1044 if(!(csr32r(ctlr, Mear) & Eedo)) 1045 break; 1046 } 1047 r &= ~Eedi; 1048 1049 data = 0; 1050 for(i = 16-1; i >= 0; i--){ 1051 csr32w(ctlr, Mear, Eeclk|r); 1052 microdelay(1); 1053 if(csr32r(ctlr, Mear) & Eedo) 1054 data |= (1<<i); 1055 csr32w(ctlr, Mear, r); 1056 microdelay(1); 1057 } 1058 1059 csr32w(ctlr, Mear, mear); 1060 1061 if(ctlr->eepromsz == 0){ 1062 ctlr->eepromsz = 8-size; 1063 ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort)); 1064 if(ctlr->eeprom == nil) 1065 error(Enomem); 1066 goto reread; 1067 } 1068 1069 return data; 1070 } 1071 1072 static int 1073 dp83820reset(Ctlr* ctlr) 1074 { 1075 int i, r; 1076 unsigned char sum; 1077 1078 /* 1079 * Soft reset the controller; 1080 * read the EEPROM to get the initial settings 1081 * of the Cfg and Gpior bits which should be cleared by 1082 * the reset. 1083 */ 1084 dp83820detach(ctlr); 1085 1086 atc93c46r(ctlr, 0); 1087 if(ctlr->eeprom == nil) { 1088 print("dp83820reset: no eeprom\n"); 1089 return -1; 1090 } 1091 sum = 0; 1092 for(i = 0; i < 0x0E; i++){ 1093 r = atc93c46r(ctlr, i); 1094 ctlr->eeprom[i] = r; 1095 sum += r; 1096 sum += r>>8; 1097 } 1098 1099 if(sum != 0){ 1100 print("dp83820reset: bad EEPROM checksum\n"); 1101 return -1; 1102 } 1103 1104 #ifdef notdef 1105 csr32w(ctlr, Gpior, ctlr->eeprom[4]); 1106 1107 cfg = Extstsen|Exd; 1108 r = csr32r(ctlr, Cfg); 1109 if(ctlr->eeprom[5] & 0x0001) 1110 cfg |= Ext125; 1111 if(ctlr->eeprom[5] & 0x0002) 1112 cfg |= M64addren; 1113 if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det)) 1114 cfg |= Data64en; 1115 if(ctlr->eeprom[5] & 0x0008) 1116 cfg |= T64addren; 1117 if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10)) 1118 cfg |= Mwidis; 1119 if(ctlr->eeprom[5] & 0x0020) 1120 cfg |= Mrmdis; 1121 if(ctlr->eeprom[5] & 0x0080) 1122 cfg |= Mode1000; 1123 if(ctlr->eeprom[5] & 0x0200) 1124 cfg |= Tbien|Mode1000; 1125 /* 1126 * What about RO bits we might have destroyed with Rst? 1127 * What about Exd, Tmrtest, Extstsen, Pintctl? 1128 * Why does it think it has detected a 64-bit bus when 1129 * it hasn't? 1130 */ 1131 #else 1132 // r = csr32r(ctlr, Cfg); 1133 // r &= ~(Mode1000|T64addren|Data64en|M64addren); 1134 // csr32w(ctlr, Cfg, r); 1135 // csr32w(ctlr, Cfg, 0x2000); 1136 #endif /* notdef */ 1137 ctlr->cfg = csr32r(ctlr, Cfg); 1138 print("cfg %8.8uX pcicfg %8.8uX\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR)); 1139 ctlr->cfg &= ~(T64addren|Data64en|M64addren); 1140 csr32w(ctlr, Cfg, ctlr->cfg); 1141 csr32w(ctlr, Mibc, Aclr|Frz); 1142 1143 return 0; 1144 } 1145 1146 static void 1147 dp83820pci(void) 1148 { 1149 void *mem; 1150 Pcidev *p; 1151 Ctlr *ctlr; 1152 1153 p = nil; 1154 while(p = pcimatch(p, 0, 0)){ 1155 if(p->ccrb != Pcibcnet || p->ccru != Pciscether) 1156 continue; 1157 1158 switch((p->did<<16)|p->vid){ 1159 default: 1160 continue; 1161 case (0x0022<<16)|0x100B: /* DP83820 (Gig-NIC) */ 1162 break; 1163 } 1164 1165 mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size); 1166 if(mem == 0){ 1167 print("DP83820: can't map %8.8luX\n", p->mem[1].bar); 1168 continue; 1169 } 1170 1171 ctlr = malloc(sizeof(Ctlr)); 1172 if(ctlr == nil) { 1173 vunmap(mem, p->mem[1].size); 1174 error(Enomem); 1175 } 1176 ctlr->port = p->mem[1].bar & ~0x0F; 1177 ctlr->pcidev = p; 1178 ctlr->id = (p->did<<16)|p->vid; 1179 1180 ctlr->nic = mem; 1181 if(dp83820reset(ctlr)){ 1182 free(ctlr); 1183 vunmap(mem, p->mem[1].size); 1184 continue; 1185 } 1186 pcisetbme(p); 1187 1188 if(dp83820ctlrhead != nil) 1189 dp83820ctlrtail->next = ctlr; 1190 else 1191 dp83820ctlrhead = ctlr; 1192 dp83820ctlrtail = ctlr; 1193 } 1194 } 1195 1196 static int 1197 dp83820pnp(Ether* edev) 1198 { 1199 int i; 1200 Ctlr *ctlr; 1201 uchar ea[Eaddrlen]; 1202 1203 if(dp83820ctlrhead == nil) 1204 dp83820pci(); 1205 1206 /* 1207 * Any adapter matches if no edev->port is supplied, 1208 * otherwise the ports must match. 1209 */ 1210 for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){ 1211 if(ctlr->active) 1212 continue; 1213 if(edev->port == 0 || edev->port == ctlr->port){ 1214 ctlr->active = 1; 1215 break; 1216 } 1217 } 1218 if(ctlr == nil) 1219 return -1; 1220 1221 edev->ctlr = ctlr; 1222 edev->port = ctlr->port; 1223 edev->irq = ctlr->pcidev->intl; 1224 edev->tbdf = ctlr->pcidev->tbdf; 1225 edev->mbps = 1000; 1226 1227 /* 1228 * Check if the adapter's station address is to be overridden. 1229 * If not, read it from the EEPROM and set in ether->ea prior to 1230 * loading the station address in the hardware. 1231 */ 1232 memset(ea, 0, Eaddrlen); 1233 if(memcmp(ea, edev->ea, Eaddrlen) == 0) 1234 for(i = 0; i < Eaddrlen/2; i++){ 1235 edev->ea[2*i] = ctlr->eeprom[0x0C-i]; 1236 edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8; 1237 } 1238 1239 edev->attach = dp83820attach; 1240 edev->transmit = dp83820transmit; 1241 edev->interrupt = dp83820interrupt; 1242 edev->ifstat = dp83820ifstat; 1243 1244 edev->arg = edev; 1245 edev->promiscuous = dp83820promiscuous; 1246 edev->multicast = dp83820multicast; 1247 edev->shutdown = dp83820shutdown; 1248 1249 return 0; 1250 } 1251 1252 void 1253 etherdp83820link(void) 1254 { 1255 addethercard("DP83820", dp83820pnp); 1256 } 1257