1 /* 2 * National Semiconductor DP83815 3 * 4 * Supports only internal PHY and has been tested on: 5 * Netgear FA311TX (using Netgear DS108 10/100 hub) 6 * SiS 900 within SiS 630 7 * To do: 8 * check Ethernet address; 9 * test autonegotiation on 10 Mbit, and 100 Mbit full duplex; 10 * external PHY via MII (should be common code for MII); 11 * thresholds; 12 * ring sizing; 13 * physical link changes/disconnect; 14 * push initialisation back to attach. 15 * 16 * C H Forsyth, forsyth@vitanuova.com, 18th June 2001. 17 */ 18 19 #include "u.h" 20 #include "../port/lib.h" 21 #include "mem.h" 22 #include "dat.h" 23 #include "fns.h" 24 #include "io.h" 25 #include "../port/error.h" 26 #include "../port/netif.h" 27 28 #include "etherif.h" 29 30 #define DEBUG 0 31 #define debug if(DEBUG)print 32 33 enum { 34 Nrde = 64, 35 Ntde = 64, 36 }; 37 38 #define Rbsz ROUNDUP(sizeof(Etherpkt)+4, 4) 39 40 typedef struct Des { 41 ulong next; 42 int cmdsts; 43 ulong addr; 44 Block* bp; 45 } Des; 46 47 enum { /* cmdsts */ 48 Own = 1<<31, /* set by data producer to hand to consumer */ 49 More = 1<<30, /* more of packet in next descriptor */ 50 Intr = 1<<29, /* interrupt when device is done with it */ 51 Supcrc = 1<<28, /* suppress crc on transmit */ 52 Inccrc = 1<<28, /* crc included on receive (always) */ 53 Ok = 1<<27, /* packet ok */ 54 Size = 0xFFF, /* packet size in bytes */ 55 56 /* transmit */ 57 Txa = 1<<26, /* transmission aborted */ 58 Tfu = 1<<25, /* transmit fifo underrun */ 59 Crs = 1<<24, /* carrier sense lost */ 60 Td = 1<<23, /* transmission deferred */ 61 Ed = 1<<22, /* excessive deferral */ 62 Owc = 1<<21, /* out of window collision */ 63 Ec = 1<<20, /* excessive collisions */ 64 /* 19-16 collision count */ 65 66 /* receive */ 67 Rxa = 1<<26, /* receive aborted (same as Rxo) */ 68 Rxo = 1<<25, /* receive overrun */ 69 Dest = 3<<23, /* destination class */ 70 Drej= 0<<23, /* packet was rejected */ 71 Duni= 1<<23, /* unicast */ 72 Dmulti= 2<<23, /* multicast */ 73 Dbroad= 3<<23, /* broadcast */ 74 Long = 1<<22, /* too long packet received */ 75 Runt = 1<<21, /* packet less than 64 bytes */ 76 Ise = 1<<20, /* invalid symbol */ 77 Crce = 1<<19, /* invalid crc */ 78 Fae = 1<<18, /* frame alignment error */ 79 Lbp = 1<<17, /* loopback packet */ 80 Col = 1<<16, /* collision during receive */ 81 }; 82 83 enum { /* PCI vendor & device IDs */ 84 Nat83815 = (0x0020<<16)|0x100B, 85 SiS = 0x1039, 86 SiS900 = (0x0900<<16)|SiS, 87 SiS7016 = (0x7016<<16)|SiS, 88 89 SiS630bridge = 0x0008, 90 91 /* SiS 900 PCI revision codes */ 92 SiSrev630s = 0x81, 93 SiSrev630e = 0x82, 94 SiSrev630ea1 = 0x83, 95 96 SiSeenodeaddr = 8, /* short addr of SiS eeprom mac addr */ 97 SiS630eenodeaddr = 9, /* likewise for the 630 */ 98 Nseenodeaddr = 6, /* " for NS eeprom */ 99 Nat83815avng = 0x403, 100 Nat83816avng = 0x505, /* 83816 acts like submodel of 83815 */ 101 /* using reg. 0x58 to disambiguate. */ 102 }; 103 104 typedef struct Ctlr Ctlr; 105 typedef struct Ctlr { 106 int port; 107 Pcidev* pcidev; 108 Ctlr* next; 109 int active; 110 int id; /* (pcidev->did<<16)|pcidev->vid */ 111 112 ushort srom[0xB+1]; 113 uchar sromea[Eaddrlen]; /* MAC address */ 114 115 uchar fd; /* option or auto negotiation */ 116 117 int mbps; 118 119 Lock lock; 120 121 Des* rdr; /* receive descriptor ring */ 122 int nrdr; /* size of rdr */ 123 int rdrx; /* index into rdr */ 124 125 Lock tlock; 126 Des* tdr; /* transmit descriptor ring */ 127 int ntdr; /* size of tdr */ 128 int tdrh; /* host index into tdr */ 129 int tdri; /* interface index into tdr */ 130 int ntq; /* descriptors active */ 131 int ntqmax; 132 133 ulong rxa; /* receive statistics */ 134 ulong rxo; 135 ulong rlong; 136 ulong runt; 137 ulong ise; 138 ulong crce; 139 ulong fae; 140 ulong lbp; 141 ulong col; 142 ulong rxsovr; 143 ulong rxorn; 144 145 ulong txa; /* transmit statistics */ 146 ulong tfu; 147 ulong crs; 148 ulong td; 149 ulong ed; 150 ulong owc; 151 ulong ec; 152 ulong txurn; 153 154 ulong dperr; /* system errors */ 155 ulong rmabt; 156 ulong rtabt; 157 ulong sserr; 158 ulong rxsover; 159 160 ulong version; /* silicon version; register 0x58h */ 161 } Ctlr; 162 163 static Ctlr* ctlrhead; 164 static Ctlr* ctlrtail; 165 166 enum { 167 /* registers (could memory map) */ 168 Rcr= 0x00, /* command register */ 169 Rst= 1<<8, 170 Rxr= 1<<5, /* receiver reset */ 171 Txr= 1<<4, /* transmitter reset */ 172 Rxd= 1<<3, /* receiver disable */ 173 Rxe= 1<<2, /* receiver enable */ 174 Txd= 1<<1, /* transmitter disable */ 175 Txe= 1<<0, /* transmitter enable */ 176 Rcfg= 0x04, /* configuration */ 177 Lnksts= 1<<31, /* link good */ 178 Speed100= 1<<30, /* 100 Mb/s link */ 179 Fdup= 1<<29, /* full duplex */ 180 Pol= 1<<28, /* polarity reversal (10baseT) */ 181 Aneg_dn= 1<<27, /* autonegotiation done */ 182 Pint_acen= 1<<17, /* PHY interrupt auto clear enable */ 183 Pause_adv= 1<<16, /* advertise pause during auto neg */ 184 Paneg_ena= 1<<13, /* auto negotiation enable */ 185 Paneg_all= 7<<13, /* auto negotiation enable 10/100 half & full */ 186 Ext_phy= 1<<12, /* enable MII for external PHY */ 187 Phy_rst= 1<<10, /* reset internal PHY */ 188 Phy_dis= 1<<9, /* disable internal PHY (eg, low power) */ 189 Req_alg= 1<<7, /* PCI bus request: set means less aggressive */ 190 Sb= 1<<6, /* single slot back-off not random */ 191 Pow= 1<<5, /* out of window timer selection */ 192 Exd= 1<<4, /* disable excessive deferral timer */ 193 Pesel= 1<<3, /* parity error algorithm selection */ 194 Brom_dis= 1<<2, /* disable boot rom interface */ 195 Bem= 1<<0, /* big-endian mode */ 196 Rmear= 0x08, /* eeprom access */ 197 Mdc= 1<<6, /* MII mangement check */ 198 Mddir= 1<<5, /* MII management direction */ 199 Mdio= 1<<4, /* MII mangement data */ 200 Eesel= 1<<3, /* EEPROM chip select */ 201 Eeclk= 1<<2, /* EEPROM clock */ 202 Eedo= 1<<1, /* EEPROM data out (from chip) */ 203 Eedi= 1<<0, /* EEPROM data in (to chip) */ 204 Rptscr= 0x0C, /* pci test control */ 205 Risr= 0x10, /* interrupt status */ 206 Txrcmp= 1<<25, /* transmit reset complete */ 207 Rxrcmp= 1<<24, /* receiver reset complete */ 208 Dperr= 1<<23, /* detected parity error */ 209 Sserr= 1<<22, /* signalled system error */ 210 Rmabt= 1<<21, /* received master abort */ 211 Rtabt= 1<<20, /* received target abort */ 212 Rxsovr= 1<<16, /* RX status FIFO overrun */ 213 Hiberr= 1<<15, /* high bits error set (OR of 25-16) */ 214 Phy= 1<<14, /* PHY interrupt */ 215 Pme= 1<<13, /* power management event (wake online) */ 216 Swi= 1<<12, /* software interrupt */ 217 Mib= 1<<11, /* MIB service */ 218 Txurn= 1<<10, /* TX underrun */ 219 Txidle= 1<<9, /* TX idle */ 220 Txerr= 1<<8, /* TX packet error */ 221 Txdesc= 1<<7, /* TX descriptor (with Intr bit done) */ 222 Txok= 1<<6, /* TX ok */ 223 Rxorn= 1<<5, /* RX overrun */ 224 Rxidle= 1<<4, /* RX idle */ 225 Rxearly= 1<<3, /* RX early threshold */ 226 Rxerr= 1<<2, /* RX packet error */ 227 Rxdesc= 1<<1, /* RX descriptor (with Intr bit done) */ 228 Rxok= 1<<0, /* RX ok */ 229 Rimr= 0x14, /* interrupt mask */ 230 Rier= 0x18, /* interrupt enable */ 231 Ie= 1<<0, /* interrupt enable */ 232 Rtxdp= 0x20, /* transmit descriptor pointer */ 233 Rtxcfg= 0x24, /* transmit configuration */ 234 Csi= 1<<31, /* carrier sense ignore (needed for full duplex) */ 235 Hbi= 1<<30, /* heartbeat ignore (needed for full duplex) */ 236 Atp= 1<<28, /* automatic padding of runt packets */ 237 Mxdma= 7<<20, /* maximum dma transfer field */ 238 Mxdma32= 4<<20, /* 4x32-bit words (32 bytes) */ 239 Mxdma64= 5<<20, /* 8x32-bit words (64 bytes) */ 240 Flth= 0x3F<<8,/* Tx fill threshold, units of 32 bytes (must be > Mxdma) */ 241 Drth= 0x3F<<0,/* Tx drain threshold (units of 32 bytes) */ 242 Flth128= 4<<8, /* fill at 128 bytes */ 243 Drth512= 16<<0, /* drain at 512 bytes */ 244 Rrxdp= 0x30, /* receive descriptor pointer */ 245 Rrxcfg= 0x34, /* receive configuration */ 246 Atx= 1<<28, /* accept transmit packets (needed for full duplex) */ 247 Rdrth= 0x1F<<1,/* Rx drain threshold (units of 32 bytes) */ 248 Rdrth64= 2<<1, /* drain at 64 bytes */ 249 Rccsr= 0x3C, /* CLKRUN control/status */ 250 Pmests= 1<<15, /* PME status */ 251 Rwcsr= 0x40, /* wake on lan control/status */ 252 Rpcr= 0x44, /* pause control/status */ 253 Rrfcr= 0x48, /* receive filter/match control */ 254 Rfen= 1<<31, /* receive filter enable */ 255 Aab= 1<<30, /* accept all broadcast */ 256 Aam= 1<<29, /* accept all multicast */ 257 Aau= 1<<28, /* accept all unicast */ 258 Apm= 1<<27, /* accept on perfect match */ 259 Apat= 0xF<<23,/* accept on pattern match */ 260 Aarp= 1<<22, /* accept ARP */ 261 Mhen= 1<<21, /* multicast hash enable */ 262 Uhen= 1<<20, /* unicast hash enable */ 263 Ulm= 1<<19, /* U/L bit mask */ 264 /* bits 0-9 are rfaddr */ 265 Rrfdr= 0x4C, /* receive filter/match data */ 266 Rbrar= 0x50, /* boot rom address */ 267 Rbrdr= 0x54, /* boot rom data */ 268 Rsrr= 0x58, /* silicon revision */ 269 Rmibc= 0x5C, /* MIB control */ 270 /* 60-78 MIB data */ 271 272 /* PHY registers */ 273 Rbmcr= 0x80, /* basic mode configuration */ 274 Reset= 1<<15, 275 Sel100= 1<<13, /* select 100Mb/sec if no auto neg */ 276 Anena= 1<<12, /* auto negotiation enable */ 277 Anrestart= 1<<9, /* restart auto negotiation */ 278 Selfdx= 1<<8, /* select full duplex if no auto neg */ 279 Rbmsr= 0x84, /* basic mode status */ 280 Ancomp= 1<<5, /* autonegotiation complete */ 281 Rphyidr1= 0x88, 282 Rphyidr2= 0x8C, 283 Ranar= 0x90, /* autonegotiation advertisement */ 284 Ranlpar= 0x94, /* autonegotiation link partner ability */ 285 Raner= 0x98, /* autonegotiation expansion */ 286 Rannptr= 0x9C, /* autonegotiation next page TX */ 287 Rphysts= 0xC0, /* PHY status */ 288 Rmicr= 0xC4, /* MII control */ 289 Inten= 1<<1, /* PHY interrupt enable */ 290 Rmisr= 0xC8, /* MII status */ 291 Rfcscr= 0xD0, /* false carrier sense counter */ 292 Rrecr= 0xD4, /* receive error counter */ 293 Rpcsr= 0xD8, /* 100Mb config/status */ 294 Rphycr= 0xE4, /* PHY control */ 295 Rtbscr= 0xE8, /* 10BaseT status/control */ 296 }; 297 298 /* 299 * eeprom addresses 300 * 7 to 9 (16 bit words): mac address, shifted and reversed 301 */ 302 303 #define csr32r(c, r) (inl((c)->port+(r))) 304 #define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l))) 305 #define csr16r(c, r) (ins((c)->port+(r))) 306 #define csr16w(c, r, l) (outs((c)->port+(r), (ulong)(l))) 307 308 static void 309 dumpcregs(Ctlr *ctlr) 310 { 311 int i; 312 313 for(i=0; i<=0x5C; i+=4) 314 print("%2.2ux %8.8lux\n", i, csr32r(ctlr, i)); 315 } 316 317 static void 318 promiscuous(void* arg, int on) 319 { 320 Ctlr *ctlr; 321 ulong w; 322 323 ctlr = ((Ether*)arg)->ctlr; 324 ilock(&ctlr->lock); 325 w = csr32r(ctlr, Rrfcr); 326 if(on != ((w&Aau)!=0)){ 327 csr32w(ctlr, Rrfcr, w & ~Rfen); 328 csr32w(ctlr, Rrfcr, Rfen | (w ^ Aau)); 329 } 330 iunlock(&ctlr->lock); 331 } 332 333 static void 334 attach(Ether* ether) 335 { 336 Ctlr *ctlr; 337 338 ctlr = ether->ctlr; 339 ilock(&ctlr->lock); 340 if(0) 341 dumpcregs(ctlr); 342 csr32w(ctlr, Rcr, Rxe); 343 iunlock(&ctlr->lock); 344 } 345 346 static long 347 ifstat(Ether* ether, void* a, long n, ulong offset) 348 { 349 Ctlr *ctlr; 350 char *buf, *p; 351 int i, l, len; 352 353 ctlr = ether->ctlr; 354 355 ether->crcs = ctlr->crce; 356 ether->frames = ctlr->runt+ctlr->ise+ctlr->rlong+ctlr->fae; 357 ether->buffs = ctlr->rxorn+ctlr->tfu; 358 ether->overflows = ctlr->rxsovr; 359 360 if(n == 0) 361 return 0; 362 363 p = malloc(READSTR); 364 if(p == nil) 365 error(Enomem); 366 l = snprint(p, READSTR, "Rxa: %lud\n", ctlr->rxa); 367 l += snprint(p+l, READSTR-l, "Rxo: %lud\n", ctlr->rxo); 368 l += snprint(p+l, READSTR-l, "Rlong: %lud\n", ctlr->rlong); 369 l += snprint(p+l, READSTR-l, "Runt: %lud\n", ctlr->runt); 370 l += snprint(p+l, READSTR-l, "Ise: %lud\n", ctlr->ise); 371 l += snprint(p+l, READSTR-l, "Fae: %lud\n", ctlr->fae); 372 l += snprint(p+l, READSTR-l, "Lbp: %lud\n", ctlr->lbp); 373 l += snprint(p+l, READSTR-l, "Tfu: %lud\n", ctlr->tfu); 374 l += snprint(p+l, READSTR-l, "Txa: %lud\n", ctlr->txa); 375 l += snprint(p+l, READSTR-l, "CRC Error: %lud\n", ctlr->crce); 376 l += snprint(p+l, READSTR-l, "Collision Seen: %lud\n", ctlr->col); 377 l += snprint(p+l, READSTR-l, "Frame Too Long: %lud\n", ctlr->rlong); 378 l += snprint(p+l, READSTR-l, "Runt Frame: %lud\n", ctlr->runt); 379 l += snprint(p+l, READSTR-l, "Rx Underflow Error: %lud\n", ctlr->rxorn); 380 l += snprint(p+l, READSTR-l, "Tx Underrun: %lud\n", ctlr->txurn); 381 l += snprint(p+l, READSTR-l, "Excessive Collisions: %lud\n", ctlr->ec); 382 l += snprint(p+l, READSTR-l, "Late Collision: %lud\n", ctlr->owc); 383 l += snprint(p+l, READSTR-l, "Loss of Carrier: %lud\n", ctlr->crs); 384 l += snprint(p+l, READSTR-l, "Parity: %lud\n", ctlr->dperr); 385 l += snprint(p+l, READSTR-l, "Aborts: %lud\n", ctlr->rmabt+ctlr->rtabt); 386 l += snprint(p+l, READSTR-l, "RX Status overrun: %lud\n", ctlr->rxsover); 387 snprint(p+l, READSTR-l, "ntqmax: %d\n", ctlr->ntqmax); 388 ctlr->ntqmax = 0; 389 buf = a; 390 len = readstr(offset, buf, n, p); 391 if(offset > l) 392 offset -= l; 393 else 394 offset = 0; 395 buf += len; 396 n -= len; 397 398 l = snprint(p, READSTR, "srom:"); 399 for(i = 0; i < nelem(ctlr->srom); i++){ 400 if(i && ((i & 0x0F) == 0)) 401 l += snprint(p+l, READSTR-l, "\n "); 402 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->srom[i]); 403 } 404 405 snprint(p+l, READSTR-l, "\n"); 406 len += readstr(offset, buf, n, p); 407 free(p); 408 409 return len; 410 } 411 412 static void 413 txstart(Ether* ether) 414 { 415 Ctlr *ctlr; 416 Block *bp; 417 Des *des; 418 int started; 419 420 ctlr = ether->ctlr; 421 started = 0; 422 while(ctlr->ntq < ctlr->ntdr-1){ 423 bp = qget(ether->oq); 424 if(bp == nil) 425 break; 426 des = &ctlr->tdr[ctlr->tdrh]; 427 des->bp = bp; 428 des->addr = PADDR(bp->rp); 429 ctlr->ntq++; 430 coherence(); 431 des->cmdsts = Own | BLEN(bp); 432 ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr); 433 started = 1; 434 } 435 if(started){ 436 coherence(); 437 csr32w(ctlr, Rcr, Txe); /* prompt */ 438 } 439 440 if(ctlr->ntq > ctlr->ntqmax) 441 ctlr->ntqmax = ctlr->ntq; 442 } 443 444 static void 445 transmit(Ether* ether) 446 { 447 Ctlr *ctlr; 448 449 ctlr = ether->ctlr; 450 ilock(&ctlr->tlock); 451 txstart(ether); 452 iunlock(&ctlr->tlock); 453 } 454 455 static void 456 txrxcfg(Ctlr *ctlr, int txdrth) 457 { 458 ulong rx, tx; 459 460 rx = csr32r(ctlr, Rrxcfg); 461 tx = csr32r(ctlr, Rtxcfg); 462 if(ctlr->fd){ 463 rx |= Atx; 464 tx |= Csi | Hbi; 465 }else{ 466 rx &= ~Atx; 467 tx &= ~(Csi | Hbi); 468 } 469 tx &= ~(Mxdma|Drth|Flth); 470 tx |= Mxdma64 | Flth128 | txdrth; 471 csr32w(ctlr, Rtxcfg, tx); 472 rx &= ~(Mxdma|Rdrth); 473 rx |= Mxdma64 | Rdrth64; 474 csr32w(ctlr, Rrxcfg, rx); 475 } 476 477 static void 478 interrupt(Ureg*, void* arg) 479 { 480 int len, status, cmdsts, n; 481 Ctlr *ctlr; 482 Ether *ether; 483 Des *des; 484 Block *bp; 485 486 ether = arg; 487 ctlr = ether->ctlr; 488 489 while((status = csr32r(ctlr, Risr)) != 0){ 490 491 status &= ~(Pme|Mib); 492 493 if(status & Hiberr){ 494 if(status & Rxsovr) 495 ctlr->rxsover++; 496 if(status & Sserr) 497 ctlr->sserr++; 498 if(status & Dperr) 499 ctlr->dperr++; 500 if(status & Rmabt) 501 ctlr->rmabt++; 502 if(status & Rtabt) 503 ctlr->rtabt++; 504 status &= ~(Hiberr|Txrcmp|Rxrcmp|Rxsovr|Dperr|Sserr|Rmabt|Rtabt); 505 } 506 507 /* update link state */ 508 if(status&Phy){ 509 status &= ~Phy; 510 csr32r(ctlr, Rcfg); 511 n = csr32r(ctlr, Rcfg); 512 // iprint("83815 phy %x %x\n", n, n&Lnksts); 513 ether->link = (n&Lnksts) != 0; 514 } 515 516 /* 517 * Received packets. 518 */ 519 if(status & (Rxdesc|Rxok|Rxerr|Rxearly|Rxorn)){ 520 des = &ctlr->rdr[ctlr->rdrx]; 521 while((cmdsts = des->cmdsts) & Own){ 522 if((cmdsts&Ok) == 0){ 523 if(cmdsts & Rxa) 524 ctlr->rxa++; 525 if(cmdsts & Rxo) 526 ctlr->rxo++; 527 if(cmdsts & Long) 528 ctlr->rlong++; 529 if(cmdsts & Runt) 530 ctlr->runt++; 531 if(cmdsts & Ise) 532 ctlr->ise++; 533 if(cmdsts & Crce) 534 ctlr->crce++; 535 if(cmdsts & Fae) 536 ctlr->fae++; 537 if(cmdsts & Lbp) 538 ctlr->lbp++; 539 if(cmdsts & Col) 540 ctlr->col++; 541 } 542 else if(bp = iallocb(Rbsz)){ 543 len = (cmdsts&Size)-4; 544 if(len <= 0){ 545 debug("ns83815: packet len %d <=0\n", len); 546 freeb(des->bp); 547 }else{ 548 des->bp->wp = des->bp->rp+len; 549 etheriq(ether, des->bp, 1); 550 } 551 des->bp = bp; 552 des->addr = PADDR(bp->rp); 553 coherence(); 554 }else{ 555 debug("ns83815: interrupt: iallocb for input buffer failed\n"); 556 des->bp->next = 0; 557 } 558 559 des->cmdsts = Rbsz; 560 coherence(); 561 562 ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr); 563 des = &ctlr->rdr[ctlr->rdrx]; 564 } 565 status &= ~(Rxdesc|Rxok|Rxerr|Rxearly|Rxorn); 566 } 567 568 /* 569 * Check the transmit side: 570 * check for Transmit Underflow and Adjust 571 * the threshold upwards; 572 * free any transmitted buffers and try to 573 * top-up the ring. 574 */ 575 if(status & Txurn){ 576 ctlr->txurn++; 577 ilock(&ctlr->lock); 578 /* change threshold */ 579 iunlock(&ctlr->lock); 580 status &= ~(Txurn); 581 } 582 583 ilock(&ctlr->tlock); 584 while(ctlr->ntq){ 585 des = &ctlr->tdr[ctlr->tdri]; 586 cmdsts = des->cmdsts; 587 if(cmdsts & Own) 588 break; 589 590 if((cmdsts & Ok) == 0){ 591 if(cmdsts & Txa) 592 ctlr->txa++; 593 if(cmdsts & Tfu) 594 ctlr->tfu++; 595 if(cmdsts & Td) 596 ctlr->td++; 597 if(cmdsts & Ed) 598 ctlr->ed++; 599 if(cmdsts & Owc) 600 ctlr->owc++; 601 if(cmdsts & Ec) 602 ctlr->ec++; 603 ether->oerrs++; 604 } 605 606 freeb(des->bp); 607 des->bp = nil; 608 des->cmdsts = 0; 609 610 ctlr->ntq--; 611 ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr); 612 } 613 txstart(ether); 614 iunlock(&ctlr->tlock); 615 616 status &= ~(Txurn|Txidle|Txerr|Txdesc|Txok); 617 618 /* 619 * Anything left not catered for? 620 */ 621 if(status) 622 print("#l%d: status %8.8uX\n", ether->ctlrno, status); 623 } 624 } 625 626 static void 627 ctlrinit(Ether* ether) 628 { 629 Ctlr *ctlr; 630 Des *des, *last; 631 632 ctlr = ether->ctlr; 633 634 /* 635 * Allocate suitable aligned descriptors 636 * for the transmit and receive rings; 637 * initialise the receive ring; 638 * initialise the transmit ring; 639 * unmask interrupts and start the transmit side. 640 */ 641 des = xspanalloc((ctlr->nrdr+ctlr->ntdr)*sizeof(Des), 32, 0); 642 ctlr->tdr = des; 643 ctlr->rdr = des+ctlr->ntdr; 644 645 last = nil; 646 for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){ 647 des->bp = iallocb(Rbsz); 648 if(des->bp == nil) 649 error(Enomem); 650 des->cmdsts = Rbsz; 651 des->addr = PADDR(des->bp->rp); 652 if(last != nil) 653 last->next = PADDR(des); 654 last = des; 655 } 656 ctlr->rdr[ctlr->nrdr-1].next = PADDR(ctlr->rdr); 657 ctlr->rdrx = 0; 658 csr32w(ctlr, Rrxdp, PADDR(ctlr->rdr)); 659 660 last = nil; 661 for(des = ctlr->tdr; des < &ctlr->tdr[ctlr->ntdr]; des++){ 662 des->cmdsts = 0; 663 des->bp = nil; 664 des->addr = ~0; 665 if(last != nil) 666 last->next = PADDR(des); 667 last = des; 668 } 669 ctlr->tdr[ctlr->ntdr-1].next = PADDR(ctlr->tdr); 670 ctlr->tdrh = 0; 671 ctlr->tdri = 0; 672 csr32w(ctlr, Rtxdp, PADDR(ctlr->tdr)); 673 674 txrxcfg(ctlr, Drth512); 675 676 csr32w(ctlr, Rimr, Dperr|Sserr|Rmabt|Rtabt|Rxsovr|Hiberr|Txurn|Txerr| 677 Txdesc|Txok|Rxorn|Rxerr|Rxdesc|Rxok); /* Phy|Pme|Mib */ 678 csr32w(ctlr, Rmicr, Inten); /* enable phy interrupts */ 679 csr32r(ctlr, Risr); /* clear status */ 680 csr32w(ctlr, Rier, Ie); 681 } 682 683 static void 684 eeclk(Ctlr *ctlr, int clk) 685 { 686 csr32w(ctlr, Rmear, Eesel | clk); 687 microdelay(2); 688 } 689 690 static void 691 eeidle(Ctlr *ctlr) 692 { 693 int i; 694 695 eeclk(ctlr, 0); 696 eeclk(ctlr, Eeclk); 697 for(i=0; i<25; i++){ 698 eeclk(ctlr, 0); 699 eeclk(ctlr, Eeclk); 700 } 701 eeclk(ctlr, 0); 702 csr32w(ctlr, Rmear, 0); 703 microdelay(2); 704 } 705 706 static ushort 707 eegetw(Ctlr *ctlr, int a) 708 { 709 int d, i, w; 710 711 eeidle(ctlr); 712 eeclk(ctlr, 0); 713 eeclk(ctlr, Eeclk); 714 d = 0x180 | a; 715 for(i=0x400; i; i>>=1){ 716 if(d & i) 717 csr32w(ctlr, Rmear, Eesel|Eedi); 718 else 719 csr32w(ctlr, Rmear, Eesel); 720 eeclk(ctlr, Eeclk); 721 eeclk(ctlr, 0); 722 microdelay(2); 723 } 724 w = 0; 725 for(i=0x8000; i; i >>= 1){ 726 eeclk(ctlr, Eeclk); 727 if(csr32r(ctlr, Rmear) & Eedo) 728 w |= i; 729 microdelay(2); 730 eeclk(ctlr, 0); 731 } 732 eeidle(ctlr); 733 return w; 734 } 735 736 static int 737 resetctlr(Ctlr *ctlr) 738 { 739 int i; 740 741 /* 742 * Soft-reset the controller 743 */ 744 csr32w(ctlr, Rcr, Rst); 745 for(i=0;; i++){ 746 if(i > 100){ 747 print("ns83815: soft reset did not complete\n"); 748 return -1; 749 } 750 microdelay(250); 751 if((csr32r(ctlr, Rcr) & Rst) == 0) 752 break; 753 delay(1); 754 } 755 return 0; 756 } 757 758 static void 759 shutdown(Ether* ether) 760 { 761 Ctlr *ctlr = ether->ctlr; 762 763 print("ether83815 shutting down\n"); 764 csr32w(ctlr, Rcr, Rxd|Txd); /* disable transceiver */ 765 resetctlr(ctlr); 766 } 767 768 static int 769 softreset(Ctlr* ctlr, int resetphys) 770 { 771 int i, w; 772 773 /* 774 * Soft-reset the controller 775 */ 776 resetctlr(ctlr); 777 csr32w(ctlr, Rccsr, Pmests); 778 csr32w(ctlr, Rccsr, 0); 779 csr32w(ctlr, Rcfg, csr32r(ctlr, Rcfg) | Pint_acen); 780 ctlr->version = csr32r(ctlr, Rsrr); 781 if(resetphys){ 782 /* 783 * Soft-reset the PHY 784 */ 785 csr32w(ctlr, Rbmcr, Reset); 786 for(i=0;; i++){ 787 if(i > 100){ 788 print("ns83815: PHY soft reset time out\n"); 789 return -1; 790 } 791 if((csr32r(ctlr, Rbmcr) & Reset) == 0) 792 break; 793 delay(1); 794 } 795 } 796 797 /* 798 * Initialisation values, in sequence (see 4.4 Recommended Registers Configuration) 799 */ 800 csr16w(ctlr, 0xCC, 0x0001); /* PGSEL */ 801 csr16w(ctlr, 0xE4, 0x189C); /* PMCCSR */ 802 csr16w(ctlr, 0xFC, 0x0000); /* TSTDAT */ 803 csr16w(ctlr, 0xF4, 0x5040); /* DSPCFG */ 804 csr16w(ctlr, 0xF8, 0x008C); /* SDCFG */ 805 806 /* 807 * Auto negotiate 808 */ 809 csr16r(ctlr, Rbmsr); /* clear latched bits */ 810 debug("anar: %4.4ux\n", csr16r(ctlr, Ranar)); 811 csr16w(ctlr, Rbmcr, Anena); 812 if(csr16r(ctlr, Ranar) == 0 || (csr32r(ctlr, Rcfg) & Aneg_dn) == 0){ 813 csr16w(ctlr, Rbmcr, Anena|Anrestart); 814 for(i=0;; i++){ 815 if(i > 3000){ 816 print("ns83815: auto neg timed out\n"); 817 return -1; 818 } 819 if((w = csr16r(ctlr, Rbmsr)) & Ancomp) 820 break; 821 delay(1); 822 } 823 debug("%d ms\n", i); 824 w &= 0xFFFF; 825 debug("bmsr: %4.4ux\n", w); 826 USED(w); 827 } 828 debug("anar: %4.4ux\n", csr16r(ctlr, Ranar)); 829 debug("anlpar: %4.4ux\n", csr16r(ctlr, Ranlpar)); 830 debug("aner: %4.4ux\n", csr16r(ctlr, Raner)); 831 debug("physts: %4.4ux\n", csr16r(ctlr, Rphysts)); 832 debug("tbscr: %4.4ux\n", csr16r(ctlr, Rtbscr)); 833 return 0; 834 } 835 836 static int 837 media(Ether* ether) 838 { 839 Ctlr* ctlr; 840 ulong cfg; 841 842 ctlr = ether->ctlr; 843 cfg = csr32r(ctlr, Rcfg); 844 ctlr->fd = (cfg & Fdup) != 0; 845 ether->link = (cfg&Lnksts) != 0; 846 return (cfg&(Lnksts|Speed100)) == Lnksts? 10: 100; 847 } 848 849 static char* mediatable[9] = { 850 "10BASE-T", /* TP */ 851 "10BASE-2", /* BNC */ 852 "10BASE-5", /* AUI */ 853 "100BASE-TX", 854 "10BASE-TFD", 855 "100BASE-TXFD", 856 "100BASE-T4", 857 "100BASE-FX", 858 "100BASE-FXFD", 859 }; 860 861 static int 862 is630(ulong id, Pcidev *p) 863 { 864 if(id == SiS900) 865 switch (p->rid) { 866 case SiSrev630s: 867 case SiSrev630e: 868 case SiSrev630ea1: 869 return 1; 870 } 871 return 0; 872 } 873 874 enum { 875 MagicReg = 0x48, 876 MagicRegSz = 1, 877 Magicrden = 0x40, /* read enable, apparently */ 878 Paddr= 0x70, /* address port */ 879 Pdata= 0x71, /* data port */ 880 }; 881 882 /* rcmos() originally from LANL's SiS 900 driver's rcmos() */ 883 static int 884 sisrdcmos(Ctlr *ctlr) 885 { 886 int i; 887 unsigned reg; 888 ulong port; 889 Pcidev *p; 890 891 debug("ns83815: SiS 630 rev. %ux reading mac address from cmos\n", ctlr->pcidev->rid); 892 p = pcimatch(nil, SiS, SiS630bridge); 893 if(p == nil) { 894 print("ns83815: no SiS 630 rev. %ux bridge for mac addr\n", 895 ctlr->pcidev->rid); 896 return 0; 897 } 898 port = p->mem[0].bar & ~0x01; 899 debug("ns83815: SiS 630 rev. %ux reading mac addr from cmos via bridge at port 0x%lux\n", ctlr->pcidev->rid, port); 900 901 reg = pcicfgr8(p, MagicReg); 902 pcicfgw8(p, MagicReg, reg|Magicrden); 903 904 for (i = 0; i < Eaddrlen; i++) { 905 outb(port+Paddr, SiS630eenodeaddr + i); 906 ctlr->sromea[i] = inb(port+Pdata); 907 } 908 909 pcicfgw8(p, MagicReg, reg & ~Magicrden); 910 return 1; 911 } 912 913 /* 914 * If this is a SiS 630E chipset with an embedded SiS 900 controller, 915 * we have to read the MAC address from the APC CMOS RAM. - sez freebsd. 916 * However, CMOS *is* NVRAM normally. See devrtc.c:440, memory.c:88. 917 */ 918 static void 919 sissrom(Ctlr *ctlr) 920 { 921 union { 922 uchar eaddr[Eaddrlen]; 923 ushort alignment; 924 } ee; 925 int i, off = SiSeenodeaddr, cnt = sizeof ee.eaddr / sizeof(short); 926 ushort *shp = (ushort *)ee.eaddr; 927 928 if(!is630(ctlr->id, ctlr->pcidev) || !sisrdcmos(ctlr)) { 929 for (i = 0; i < cnt; i++) 930 *shp++ = eegetw(ctlr, off++); 931 memmove(ctlr->sromea, ee.eaddr, sizeof ctlr->sromea); 932 } 933 } 934 935 ushort 936 søkrisee(Ctlr *c, int n) 937 { 938 int i; 939 uint cmd; 940 ushort r; 941 942 csr32w(c, Rmear, Eesel); 943 944 cmd = 0x180|n; 945 for(i = 10; i >= 0; i--){ 946 n = 1<<3; 947 if(cmd&(1<<i)) 948 n |= 1; 949 csr32w(c, Rmear, n); 950 csr32r(c, Rmear); 951 csr32w(c, Rmear, n|4); 952 csr32r(c, Rmear); 953 } 954 955 csr32w(c, Rmear, 1<<3); 956 csr32r(c, Rmear); 957 958 r = 0; 959 for(i = 0; i < 16; i++){ 960 csr32w(c, Rmear, 1<<3 | 1<<2); 961 csr32r(c, Rmear); 962 if(csr32r(c, Rmear) & 2) 963 r |= 1<<i; 964 csr32w(c, Rmear, 1<<3); 965 csr32r(c, Rmear); 966 } 967 968 csr32w(c, Rmear, 1<<3); 969 csr32w(c, Rmear, 0); 970 971 return r; 972 } 973 974 static void 975 nsnormalea(Ctlr *ctlr) 976 { 977 int i, j; 978 979 /* 980 * the MAC address is reversed, straddling word boundaries 981 */ 982 j = Nseenodeaddr*16 + 15; 983 for(i = 0; i < 48; i++){ 984 ctlr->sromea[i>>3] |= ((ctlr->srom[j>>4] >> (15-(j&0xF))) & 1) << (i&7); 985 j++; 986 } 987 } 988 989 static void 990 ns403ea(Ctlr *ctlr) 991 { 992 int i; 993 ushort s, t; 994 995 s = ctlr->srom[6]; 996 for(i = 0; i < 3; i++){ 997 t = ctlr->srom[i+7]; 998 ctlr->sromea[i*2] = t<<1 | s>>15; 999 ctlr->sromea[i*2+1] = t>>7; 1000 s = t; 1001 } 1002 } 1003 1004 static void 1005 nssrom(Ctlr* ctlr) 1006 { 1007 int i, ns403; 1008 ulong vers; 1009 ushort (*ee)(Ctlr*, int); 1010 1011 vers = ctlr->version; 1012 ns403 = vers == Nat83815avng || vers == Nat83816avng; 1013 if(ns403){ 1014 ee = søkrisee; 1015 print("soekris %lx\n", vers); 1016 }else 1017 ee = eegetw; 1018 1019 for(i = 0; i < nelem(ctlr->srom); i++) 1020 ctlr->srom[i] = ee(ctlr, i); 1021 1022 if(ns403) 1023 ns403ea(ctlr); 1024 else 1025 nsnormalea(ctlr); 1026 } 1027 1028 static void 1029 srom(Ctlr* ctlr) 1030 { 1031 memset(ctlr->sromea, 0, sizeof(ctlr->sromea)); 1032 switch (ctlr->id) { 1033 case SiS900: 1034 case SiS7016: 1035 sissrom(ctlr); 1036 break; 1037 case Nat83815: 1038 nssrom(ctlr); 1039 break; 1040 default: 1041 print("ns83815: srom: unknown id 0x%ux\n", ctlr->id); 1042 break; 1043 } 1044 } 1045 1046 static void 1047 scanpci83815(void) 1048 { 1049 Ctlr *ctlr; 1050 Pcidev *p; 1051 ulong id; 1052 1053 p = nil; 1054 while(p = pcimatch(p, 0, 0)){ 1055 if(p->ccrb != Pcibcnet || p->ccru != 0) 1056 continue; 1057 id = (p->did<<16)|p->vid; 1058 switch(id){ 1059 default: 1060 continue; 1061 1062 case Nat83815: 1063 break; 1064 case SiS900: 1065 break; 1066 } 1067 1068 /* 1069 * bar[0] is the I/O port register address and 1070 * bar[1] is the memory-mapped register address. 1071 */ 1072 ctlr = malloc(sizeof(Ctlr)); 1073 if(ctlr == nil) 1074 error(Enomem); 1075 ctlr->port = p->mem[0].bar & ~0x01; 1076 ctlr->pcidev = p; 1077 ctlr->id = id; 1078 1079 if(ioalloc(ctlr->port, p->mem[0].size, 0, "ns83815") < 0){ 1080 print("ns83815: port 0x%uX in use\n", ctlr->port); 1081 free(ctlr); 1082 continue; 1083 } 1084 1085 if(softreset(ctlr, 0) == -1){ 1086 free(ctlr); 1087 continue; 1088 } 1089 srom(ctlr); 1090 1091 if(ctlrhead != nil) 1092 ctlrtail->next = ctlr; 1093 else 1094 ctlrhead = ctlr; 1095 ctlrtail = ctlr; 1096 } 1097 } 1098 1099 /* multicast already on, don't need to do anything */ 1100 static void 1101 multicast(void*, uchar*, int) 1102 { 1103 } 1104 1105 static int 1106 reset(Ether* ether) 1107 { 1108 Ctlr *ctlr; 1109 int i, x; 1110 ulong ctladdr; 1111 uchar ea[Eaddrlen]; 1112 static int scandone; 1113 1114 if(scandone == 0){ 1115 scanpci83815(); 1116 scandone = 1; 1117 } 1118 1119 /* 1120 * Any adapter matches if no ether->port is supplied, 1121 * otherwise the ports must match. 1122 */ 1123 for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){ 1124 if(ctlr->active) 1125 continue; 1126 if(ether->port == 0 || ether->port == ctlr->port){ 1127 ctlr->active = 1; 1128 break; 1129 } 1130 } 1131 if(ctlr == nil) 1132 return -1; 1133 1134 ether->ctlr = ctlr; 1135 ether->port = ctlr->port; 1136 ether->irq = ctlr->pcidev->intl; 1137 ether->tbdf = ctlr->pcidev->tbdf; 1138 1139 /* 1140 * Check if the adapter's station address is to be overridden. 1141 * If not, read it from the EEPROM and set in ether->ea prior to 1142 * loading the station address in the hardware. 1143 */ 1144 memset(ea, 0, Eaddrlen); 1145 if(memcmp(ea, ether->ea, Eaddrlen) == 0) 1146 memmove(ether->ea, ctlr->sromea, Eaddrlen); 1147 for(i=0; i<Eaddrlen; i+=2){ 1148 x = ether->ea[i] | (ether->ea[i+1]<<8); 1149 ctladdr = (ctlr->id == Nat83815? i: i<<15); 1150 csr32w(ctlr, Rrfcr, ctladdr); 1151 csr32w(ctlr, Rrfdr, x); 1152 } 1153 csr32w(ctlr, Rrfcr, Rfen|Apm|Aab|Aam); 1154 1155 ether->mbps = media(ether); 1156 1157 /* 1158 * Look for a medium override in case there's no autonegotiation 1159 * the autonegotiation fails. 1160 */ 1161 1162 for(i = 0; i < ether->nopt; i++){ 1163 if(cistrcmp(ether->opt[i], "FD") == 0){ 1164 ctlr->fd = 1; 1165 continue; 1166 } 1167 for(x = 0; x < nelem(mediatable); x++){ 1168 debug("compare <%s> <%s>\n", mediatable[x], 1169 ether->opt[i]); 1170 if(cistrcmp(mediatable[x], ether->opt[i]) == 0){ 1171 if(x != 4 && x >= 3) 1172 ether->mbps = 100; 1173 else 1174 ether->mbps = 10; 1175 switch(x){ 1176 default: 1177 ctlr->fd = 0; 1178 break; 1179 1180 case 0x04: /* 10BASE-TFD */ 1181 case 0x05: /* 100BASE-TXFD */ 1182 case 0x08: /* 100BASE-FXFD */ 1183 ctlr->fd = 1; 1184 break; 1185 } 1186 break; 1187 } 1188 } 1189 } 1190 1191 /* 1192 * Initialise descriptor rings, ethernet address. 1193 */ 1194 ctlr->nrdr = Nrde; 1195 ctlr->ntdr = Ntde; 1196 pcisetbme(ctlr->pcidev); 1197 ctlrinit(ether); 1198 1199 /* 1200 * Linkage to the generic ethernet driver. 1201 */ 1202 ether->attach = attach; 1203 ether->transmit = transmit; 1204 ether->interrupt = interrupt; 1205 ether->ifstat = ifstat; 1206 1207 ether->arg = ether; 1208 ether->promiscuous = promiscuous; 1209 ether->multicast = multicast; 1210 ether->shutdown = shutdown; 1211 return 0; 1212 } 1213 1214 void 1215 ether83815link(void) 1216 { 1217 addethercard("83815", reset); 1218 } 1219