1 /* 2 * FCCn ethernet 3 */ 4 5 #include "u.h" 6 #include "../port/lib.h" 7 #include "mem.h" 8 #include "dat.h" 9 #include "fns.h" 10 #include "io.h" 11 #include "imm.h" 12 #include "../port/error.h" 13 #include "../port/netif.h" 14 15 #include "etherif.h" 16 #include "../ppc/ethermii.h" 17 18 #define DBG 1 19 20 enum { 21 Nrdre = 128, /* receive descriptor ring entries */ 22 Ntdre = 128, /* transmit descriptor ring entries */ 23 24 Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */ 25 Bufsize = Rbsize+CACHELINESZ, /* extra room for alignment */ 26 }; 27 28 enum { 29 30 /* ether-specific Rx BD bits */ 31 RxMiss= SBIT(7), 32 RxeLG= SBIT(10), 33 RxeNO= SBIT(11), 34 RxeSH= SBIT(12), 35 RxeCR= SBIT(13), 36 RxeOV= SBIT(14), 37 RxeCL= SBIT(15), 38 RxError= (RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL), /* various error flags */ 39 40 /* ether-specific Tx BD bits */ 41 TxPad= SBIT(1), /* pad short frames */ 42 TxTC= SBIT(5), /* transmit CRC */ 43 TxeDEF= SBIT(6), 44 TxeHB= SBIT(7), 45 TxeLC= SBIT(8), 46 TxeRL= SBIT(9), 47 TxeUN= SBIT(14), 48 TxeCSL= SBIT(15), 49 50 /* psmr */ 51 CRCE= BIT(24), /* Ethernet CRC */ 52 FCE= BIT(10), /* flow control */ 53 PRO= BIT(9), /* promiscuous mode */ 54 FDE= BIT(5), /* full duplex ethernet */ 55 LPB= BIT(3), /* local protect bit */ 56 57 /* gfmr */ 58 ENET= 0xc, /* ethernet mode */ 59 ENT= BIT(27), 60 ENR= BIT(26), 61 TCI= BIT(2), 62 63 /* FCC function code register */ 64 GBL= 0x20, 65 BO= 0x18, 66 EB= 0x10, /* Motorola byte order */ 67 TC2= 0x04, 68 DTB= 0x02, 69 BDB= 0x01, 70 71 /* FCC Event/Mask bits */ 72 GRA= SBIT(8), 73 RXC= SBIT(9), 74 TXC= SBIT(10), 75 TXE= SBIT(11), 76 RXF= SBIT(12), 77 BSY= SBIT(13), 78 TXB= SBIT(14), 79 RXB= SBIT(15), 80 }; 81 82 enum { /* Mcr */ 83 MDIread = 0x60020000, /* read opcode */ 84 MDIwrite = 0x50020000, /* write opcode */ 85 }; 86 87 typedef struct Etherparam Etherparam; 88 struct Etherparam { 89 /*0x00*/ FCCparam; 90 /*0x3c*/ ulong stat_buf; 91 /*0x40*/ ulong cam_ptr; 92 /*0x44*/ ulong cmask; 93 /*0x48*/ ulong cpres; 94 /*0x4c*/ ulong crcec; 95 /*0x50*/ ulong alec; 96 /*0x54*/ ulong disfc; 97 /*0x58*/ ushort retlim; 98 /*0x5a*/ ushort retcnt; 99 /*0x5c*/ ushort p_per; 100 /*0x5e*/ ushort boff_cnt; 101 /*0x60*/ ulong gaddr[2]; 102 /*0x68*/ ushort tfcstat; 103 /*0x6a*/ ushort tfclen; 104 /*0x6c*/ ulong tfcptr; 105 /*0x70*/ ushort mflr; 106 /*0x72*/ ushort paddr[3]; 107 /*0x78*/ ushort ibd_cnt; 108 /*0x7a*/ ushort ibd_start; 109 /*0x7c*/ ushort ibd_end; 110 /*0x7e*/ ushort tx_len; 111 /*0x80*/ uchar ibd_base[32]; 112 /*0xa0*/ ulong iaddr[2]; 113 /*0xa8*/ ushort minflr; 114 /*0xaa*/ ushort taddr[3]; 115 /*0xb0*/ ushort padptr; 116 /*0xb2*/ ushort Rsvdb2; 117 /*0xb4*/ ushort cf_range; 118 /*0xb6*/ ushort max_b; 119 /*0xb8*/ ushort maxd1; 120 /*0xba*/ ushort maxd2; 121 /*0xbc*/ ushort maxd; 122 /*0xbe*/ ushort dma_cnt; 123 /*0xc0*/ ulong octc; 124 /*0xc4*/ ulong colc; 125 /*0xc8*/ ulong broc; 126 /*0xcc*/ ulong mulc; 127 /*0xd0*/ ulong uspc; 128 /*0xd4*/ ulong frgc; 129 /*0xd8*/ ulong ospc; 130 /*0xdc*/ ulong jbrc; 131 /*0xe0*/ ulong p64c; 132 /*0xe4*/ ulong p65c; 133 /*0xe8*/ ulong p128c; 134 /*0xec*/ ulong p256c; 135 /*0xf0*/ ulong p512c; 136 /*0xf4*/ ulong p1024c; 137 /*0xf8*/ ulong cam_buf; 138 /*0xfc*/ ulong Rsvdfc; 139 /*0x100*/ 140 }; 141 142 typedef struct Ctlr Ctlr; 143 struct Ctlr { 144 Lock; 145 int fccid; 146 int port; 147 ulong pmdio; 148 ulong pmdck; 149 int init; 150 int active; 151 int duplex; /* 1 == full */ 152 FCC* fcc; 153 154 Ring; 155 Block* rcvbufs[Nrdre]; 156 Mii* mii; 157 Timer; 158 159 ulong interrupts; /* statistics */ 160 ulong deferred; 161 ulong heartbeat; 162 ulong latecoll; 163 ulong retrylim; 164 ulong underrun; 165 ulong overrun; 166 ulong carrierlost; 167 ulong retrycount; 168 }; 169 170 static int fccirq[] = {0x20, 0x21, 0x22}; 171 static int fccid[] = {FCC1ID, FCC2ID, FCC3ID}; 172 173 #ifdef DBG 174 ulong fccrhisto[16]; 175 ulong fccthisto[16]; 176 ulong fccrthisto[16]; 177 ulong fcctrhisto[16]; 178 ulong ehisto[0x80]; 179 #endif 180 181 static int fccmiimir(Mii*, int, int); 182 static int fccmiimiw(Mii*, int, int, int); 183 static void fccltimer(Ureg*, Timer*); 184 185 static void 186 attach(Ether *ether) 187 { 188 Ctlr *ctlr; 189 190 ctlr = ether->ctlr; 191 ilock(ctlr); 192 ctlr->active = 1; 193 ctlr->fcc->gfmr |= ENR|ENT; 194 iunlock(ctlr); 195 ctlr->tmode = Tperiodic; 196 ctlr->tf = fccltimer; 197 ctlr->ta = ether; 198 ctlr->tns = 5000000000LL; /* 5 seconds */ 199 timeradd(ctlr); 200 } 201 202 static void 203 closed(Ether *ether) 204 { 205 Ctlr *ctlr; 206 207 ctlr = ether->ctlr; 208 ilock(ctlr); 209 ctlr->active = 0; 210 ctlr->fcc->gfmr &= ~(ENR|ENT); 211 iunlock(ctlr); 212 print("Ether closed\n"); 213 } 214 215 static void 216 promiscuous(void* arg, int on) 217 { 218 Ether *ether; 219 Ctlr *ctlr; 220 221 ether = (Ether*)arg; 222 ctlr = ether->ctlr; 223 224 ilock(ctlr); 225 if(on || ether->nmaddr) 226 ctlr->fcc->fpsmr |= PRO; 227 else 228 ctlr->fcc->fpsmr &= ~PRO; 229 iunlock(ctlr); 230 } 231 232 static void 233 multicast(void* arg, uchar *addr, int on) 234 { 235 Ether *ether; 236 Ctlr *ctlr; 237 238 USED(addr, on); /* if on, could SetGroupAddress; if !on, it's hard */ 239 240 ether = (Ether*)arg; 241 ctlr = ether->ctlr; 242 243 ilock(ctlr); 244 if(ether->prom || ether->nmaddr) 245 ctlr->fcc->fpsmr |= PRO; 246 else 247 ctlr->fcc->fpsmr &= ~PRO; 248 iunlock(ctlr); 249 } 250 251 static void 252 txstart(Ether *ether) 253 { 254 int len; 255 Ctlr *ctlr; 256 Block *b; 257 BD *dre; 258 259 ctlr = ether->ctlr; 260 if(ctlr->init) 261 return; 262 while(ctlr->ntq < Ntdre-1){ 263 b = qget(ether->oq); 264 if(b == 0) 265 break; 266 267 dre = &ctlr->tdr[ctlr->tdrh]; 268 dczap(dre, sizeof(BD)); 269 if(dre->status & BDReady) 270 panic("ether: txstart"); 271 272 /* 273 * Give ownership of the descriptor to the chip, increment the 274 * software ring descriptor pointer and tell the chip to poll. 275 */ 276 len = BLEN(b); 277 if(ctlr->txb[ctlr->tdrh] != nil) 278 panic("fcc/ether: txstart"); 279 ctlr->txb[ctlr->tdrh] = b; 280 if((ulong)b->rp&1) 281 panic("fcc/ether: txstart align"); /* TO DO: ensure alignment */ 282 dre->addr = PADDR(b->rp); 283 dre->length = len; 284 dcflush(b->rp, len); 285 dcflush(dre, sizeof(BD)); 286 dre->status = (dre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC; 287 dcflush(dre, sizeof(BD)); 288 /* ctlr->fcc->ftodr = 1<<15; /* transmit now; Don't do this according to errata */ 289 ctlr->ntq++; 290 ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre); 291 } 292 } 293 294 static void 295 transmit(Ether* ether) 296 { 297 Ctlr *ctlr; 298 299 ctlr = ether->ctlr; 300 ilock(ctlr); 301 txstart(ether); 302 iunlock(ctlr); 303 } 304 305 static void 306 interrupt(Ureg*, void *arg) 307 { 308 int len, status, rcvd, xmtd, restart; 309 ushort events; 310 Ctlr *ctlr; 311 BD *dre; 312 Block *b, *nb; 313 Ether *ether = arg; 314 315 ctlr = ether->ctlr; 316 if(!ctlr->active) 317 return; /* not ours */ 318 319 /* 320 * Acknowledge all interrupts and whine about those that shouldn't 321 * happen. 322 */ 323 events = ctlr->fcc->fcce; 324 ctlr->fcc->fcce = events; /* clear events */ 325 326 #ifdef DBG 327 ehisto[events & 0x7f]++; 328 #endif 329 330 ctlr->interrupts++; 331 332 if(events & BSY) 333 ctlr->overrun++; 334 if(events & TXE) 335 ether->oerrs++; 336 337 #ifdef DBG 338 rcvd = xmtd = 0; 339 #endif 340 /* 341 * Receiver interrupt: run round the descriptor ring logging 342 * errors and passing valid receive data up to the higher levels 343 * until we encounter a descriptor still owned by the chip. 344 */ 345 if(events & RXF){ 346 dre = &ctlr->rdr[ctlr->rdrx]; 347 dczap(dre, sizeof(BD)); 348 while(((status = dre->status) & BDEmpty) == 0){ 349 rcvd++; 350 if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ 351 if(status & (RxeLG|RxeSH)) 352 ether->buffs++; 353 if(status & RxeNO) 354 ether->frames++; 355 if(status & RxeCR) 356 ether->crcs++; 357 if(status & RxeOV) 358 ether->overflows++; 359 print("eth rx: %ux\n", status); 360 }else{ 361 /* 362 * We have a packet. Read it in. 363 */ 364 len = dre->length-4; 365 b = ctlr->rcvbufs[ctlr->rdrx]; 366 assert(dre->addr == PADDR(b->rp)); 367 dczap(b->rp, len); 368 if(nb = iallocb(Bufsize)){ 369 b->wp += len; 370 etheriq(ether, b, 1); 371 b = nb; 372 b->rp = (uchar*)(((ulong)b->rp + CACHELINESZ-1) & ~(CACHELINESZ-1)); 373 b->wp = b->rp; 374 ctlr->rcvbufs[ctlr->rdrx] = b; 375 ctlr->rdr[ctlr->rdrx].addr = PADDR(b->wp); 376 }else 377 ether->soverflows++; 378 } 379 380 /* 381 * Finished with this descriptor, reinitialise it, 382 * give it back to the chip, then on to the next... 383 */ 384 dre->length = 0; 385 dre->status = (status & BDWrap) | BDEmpty | BDInt; 386 dcflush(dre, sizeof(BD)); 387 388 ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre); 389 dre = &ctlr->rdr[ctlr->rdrx]; 390 dczap(dre, sizeof(BD)); 391 } 392 } 393 394 /* 395 * Transmitter interrupt: handle anything queued for a free descriptor. 396 */ 397 if(events & (TXB|TXE)){ 398 ilock(ctlr); 399 restart = 0; 400 while(ctlr->ntq){ 401 dre = &ctlr->tdr[ctlr->tdri]; 402 dczap(dre, sizeof(BD)); 403 status = dre->status; 404 if(status & BDReady) 405 break; 406 if(status & TxeDEF) 407 ctlr->deferred++; 408 if(status & TxeHB) 409 ctlr->heartbeat++; 410 if(status & TxeLC) 411 ctlr->latecoll++; 412 if(status & TxeRL) 413 ctlr->retrylim++; 414 if(status & TxeUN) 415 ctlr->underrun++; 416 if(status & TxeCSL) 417 ctlr->carrierlost++; 418 if(status & (TxeLC|TxeRL|TxeUN)) 419 restart = 1; 420 ctlr->retrycount += (status>>2)&0xF; 421 b = ctlr->txb[ctlr->tdri]; 422 if(b == nil) 423 panic("fcce/interrupt: bufp"); 424 ctlr->txb[ctlr->tdri] = nil; 425 freeb(b); 426 ctlr->ntq--; 427 ctlr->tdri = NEXT(ctlr->tdri, Ntdre); 428 xmtd++; 429 } 430 431 if(restart){ 432 ctlr->fcc->gfmr &= ~ENT; 433 delay(10); 434 ctlr->fcc->gfmr |= ENT; 435 cpmop(RestartTx, ctlr->fccid, 0xc); 436 } 437 txstart(ether); 438 iunlock(ctlr); 439 } 440 #ifdef DBG 441 if(rcvd >= nelem(fccrhisto)) 442 rcvd = nelem(fccrhisto) - 1; 443 if(xmtd >= nelem(fccthisto)) 444 xmtd = nelem(fccthisto) - 1; 445 if(rcvd) 446 fcctrhisto[xmtd]++; 447 else 448 fccthisto[xmtd]++; 449 if(xmtd) 450 fccrthisto[rcvd]++; 451 else 452 fccrhisto[rcvd]++; 453 #endif 454 } 455 456 static long 457 ifstat(Ether* ether, void* a, long n, ulong offset) 458 { 459 char *p; 460 int len, i, r; 461 Ctlr *ctlr; 462 MiiPhy *phy; 463 464 if(n == 0) 465 return 0; 466 467 ctlr = ether->ctlr; 468 469 p = malloc(READSTR); 470 len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); 471 len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); 472 len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); 473 len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); 474 len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount); 475 len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); 476 len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); 477 len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun); 478 len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); 479 miistatus(ctlr->mii); 480 phy = ctlr->mii->curphy; 481 len += snprint(p+len, READSTR-len, "phy: link=%d, tfc=%d, rfc=%d, speed=%d, fd=%d\n", 482 phy->link, phy->tfc, phy->rfc, phy->speed, phy->fd); 483 484 #ifdef DBG 485 if(ctlr->mii != nil && ctlr->mii->curphy != nil){ 486 len += snprint(p+len, READSTR, "phy: "); 487 for(i = 0; i < NMiiPhyr; i++){ 488 if(i && ((i & 0x07) == 0)) 489 len += snprint(p+len, READSTR-len, "\n "); 490 r = miimir(ctlr->mii, i); 491 len += snprint(p+len, READSTR-len, " %4.4uX", r); 492 } 493 snprint(p+len, READSTR-len, "\n"); 494 } 495 #endif 496 snprint(p+len, READSTR-len, "\n"); 497 498 n = readstr(offset, a, n, p); 499 free(p); 500 501 return n; 502 } 503 504 IMM* imm; 505 506 /* 507 * This follows the MPC8260 user guide: section28.9's initialisation sequence. 508 */ 509 static int 510 fccsetup(Ctlr *ctlr, FCC *fcc, uchar *ea) 511 { 512 int i; 513 Etherparam *p; 514 MiiPhy *phy; 515 516 /* Turn Ethernet off */ 517 fcc->gfmr &= ~(ENR | ENT); 518 519 ioplock(); 520 switch(ctlr->port) { 521 default: 522 iopunlock(); 523 return -1; 524 case 0: 525 /* Step 1 (Section 28.9), write the parallel ports */ 526 ctlr->pmdio = 0x01000000; 527 ctlr->pmdck = 0x08000000; 528 imm->port[0].pdir &= ~A1dir0; 529 imm->port[0].pdir |= A1dir1; 530 imm->port[0].psor &= ~A1psor0; 531 imm->port[0].psor |= A1psor1; 532 imm->port[0].ppar |= (A1dir0 | A1dir1); 533 /* Step 2, Port C clocks */ 534 imm->port[2].psor &= ~0x00000c00; 535 imm->port[2].pdir &= ~0x00000c00; 536 imm->port[2].ppar |= 0x00000c00; 537 imm->port[3].pdat |= (ctlr->pmdio | ctlr->pmdck); 538 imm->port[3].podr |= ctlr->pmdio; 539 imm->port[3].pdir |= (ctlr->pmdio | ctlr->pmdck); 540 imm->port[3].ppar &= ~(ctlr->pmdio | ctlr->pmdck); 541 eieio(); 542 /* Step 3, Serial Interface clock routing */ 543 imm->cmxfcr &= ~0xff000000; /* Clock mask */ 544 imm->cmxfcr |= 0x37000000; /* Clock route */ 545 break; 546 547 case 1: 548 /* Step 1 (Section 28.9), write the parallel ports */ 549 ctlr->pmdio = 0x00400000; 550 ctlr->pmdck = 0x00200000; 551 imm->port[1].pdir &= ~B2dir0; 552 imm->port[1].pdir |= B2dir1; 553 imm->port[1].psor &= ~B2psor0; 554 imm->port[1].psor |= B2psor1; 555 imm->port[1].ppar |= (B2dir0 | B2dir1); 556 /* Step 2, Port C clocks */ 557 imm->port[2].psor &= ~0x00003000; 558 imm->port[2].pdir &= ~0x00003000; 559 imm->port[2].ppar |= 0x00003000; 560 561 imm->port[2].pdat |= (ctlr->pmdio | ctlr->pmdck); 562 imm->port[2].podr |= ctlr->pmdio; 563 imm->port[2].pdir |= (ctlr->pmdio | ctlr->pmdck); 564 imm->port[2].ppar &= ~(ctlr->pmdio | ctlr->pmdck); 565 eieio(); 566 /* Step 3, Serial Interface clock routing */ 567 imm->cmxfcr &= ~0x00ff0000; 568 imm->cmxfcr |= 0x00250000; 569 break; 570 571 case 2: 572 /* Step 1 (Section 28.9), write the parallel ports */ 573 imm->port[1].pdir &= ~B3dir0; 574 imm->port[1].pdir |= B3dir1; 575 imm->port[1].psor &= ~B3psor0; 576 imm->port[1].psor |= B3psor1; 577 imm->port[1].ppar |= (B3dir0 | B3dir1); 578 /* Step 2, Port C clocks */ 579 imm->port[2].psor &= ~0x0000c000; 580 imm->port[2].pdir &= ~0x0000c000; 581 imm->port[2].ppar |= 0x0000c000; 582 imm->port[3].pdat |= (ctlr->pmdio | ctlr->pmdck); 583 imm->port[3].podr |= ctlr->pmdio; 584 imm->port[3].pdir |= (ctlr->pmdio | ctlr->pmdck); 585 imm->port[3].ppar &= ~(ctlr->pmdio | ctlr->pmdck); 586 eieio(); 587 /* Step 3, Serial Interface clock routing */ 588 imm->cmxfcr &= ~0x0000ff00; 589 imm->cmxfcr |= 0x00003700; 590 break; 591 } 592 iopunlock(); 593 594 p = (Etherparam*)(m->immr->prmfcc + ctlr->port); 595 memset(p, 0, sizeof(Etherparam)); 596 597 /* Step 4 */ 598 fcc->gfmr |= ENET; 599 600 /* Step 5 */ 601 fcc->fpsmr = CRCE | FDE | LPB; /* full duplex operation */ 602 ctlr->duplex = ~0; 603 604 /* Step 6 */ 605 fcc->fdsr = 0xd555; 606 607 /* Step 7, initialize parameter ram */ 608 p->rbase = PADDR(ctlr->rdr); 609 p->tbase = PADDR(ctlr->tdr); 610 p->rstate = (GBL | EB) << 24; 611 p->tstate = (GBL | EB) << 24; 612 613 p->cmask = 0xdebb20e3; 614 p->cpres = 0xffffffff; 615 616 p->retlim = 15; /* retry limit */ 617 618 p->mrblr = (Rbsize+0x1f)&~0x1f; /* multiple of 32 */ 619 p->mflr = Rbsize; 620 p->minflr = ETHERMINTU; 621 p->maxd1 = (Rbsize+7) & ~7; 622 p->maxd2 = (Rbsize+7) & ~7; 623 624 for(i=0; i<Eaddrlen; i+=2) 625 p->paddr[2-i/2] = (ea[i+1]<<8)|ea[i]; 626 627 /* Step 7, initialize parameter ram, configuration-dependent values */ 628 p->riptr = m->immr->fccextra[ctlr->port].ri - (uchar*)IMMR; 629 p->tiptr = m->immr->fccextra[ctlr->port].ti - (uchar*)IMMR; 630 p->padptr = m->immr->fccextra[ctlr->port].pad - (uchar*)IMMR; 631 memset(m->immr->fccextra[ctlr->port].pad, 0x88, 0x20); 632 633 /* Step 8, clear out events */ 634 fcc->fcce = ~0; 635 636 /* Step 9, Interrupt enable */ 637 fcc->fccm = TXE | RXF | TXB; 638 639 /* Step 10, Configure interrupt priority (not done here) */ 640 /* Step 11, Clear out current events */ 641 /* Step 12, Enable interrupts to the CP interrupt controller */ 642 643 /* Step 13, Issue the Init Tx and Rx command, specifying 0xc for ethernet*/ 644 cpmop(InitRxTx, fccid[ctlr->port], 0xc); 645 646 /* Step 14, Link management */ 647 if((ctlr->mii = malloc(sizeof(Mii))) == nil) 648 return -1; 649 ctlr->mii->mir = fccmiimir; 650 ctlr->mii->miw = fccmiimiw; 651 ctlr->mii->ctlr = ctlr; 652 653 if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){ 654 free(ctlr->mii); 655 ctlr->mii = nil; 656 return -1; 657 } 658 miiane(ctlr->mii, ~0, ~0, ~0); 659 #ifdef DBG 660 print("oui=%X, phyno=%d, ", phy->oui, phy->phyno); 661 print("anar=%ux, ", phy->anar); 662 print("fc=%ux, ", phy->fc); 663 print("mscr=%ux, ", phy->mscr); 664 665 print("link=%ux, ", phy->link); 666 print("speed=%ux, ", phy->speed); 667 print("fd=%ux, ", phy->fd); 668 print("rfc=%ux, ", phy->rfc); 669 print("tfc=%ux\n", phy->tfc); 670 #endif 671 /* Step 15, Enable ethernet: done at attach time */ 672 return 0; 673 } 674 675 static int 676 reset(Ether* ether) 677 { 678 uchar ea[Eaddrlen]; 679 Ctlr *ctlr; 680 FCC *fcc; 681 Block *b; 682 int i; 683 684 if(m->cpuhz < 24000000){ 685 print("%s ether: system speed must be >= 24MHz for ether use\n", ether->type); 686 return -1; 687 } 688 689 if(ether->port > 3){ 690 print("%s ether: no FCC port %ld\n", ether->type, ether->port); 691 return -1; 692 } 693 ether->irq = fccirq[ether->port]; 694 ether->tbdf = BusPPC; 695 fcc = imm->fcc + ether->port; 696 697 ctlr = malloc(sizeof(*ctlr)); 698 ether->ctlr = ctlr; 699 memset(ctlr, 0, sizeof(*ctlr)); 700 ctlr->fcc = fcc; 701 ctlr->port = ether->port; 702 ctlr->fccid = fccid[ether->port]; 703 704 /* Ioringinit will allocate the buffer descriptors in normal memory 705 * and NOT in Dual-Ported Ram, as prescribed by the MPC8260 706 * PowerQUICC II manual (Section 28.6). When they are allocated 707 * in DPram and the Dcache is enabled, the processor will hang 708 */ 709 if(ioringinit(ctlr, Nrdre, Ntdre, 0) < 0) 710 panic("etherfcc init"); 711 for(i = 0; i < Nrdre; i++){ 712 b = iallocb(Bufsize); 713 b->rp = (uchar*)(((ulong)b->rp + CACHELINESZ-1) & ~(CACHELINESZ-1)); 714 b->wp = b->rp; 715 ctlr->rcvbufs[i] = b; 716 ctlr->rdr[i].addr = PADDR(b->wp); 717 } 718 719 fccsetup(ctlr, fcc, ether->ea); 720 721 ether->mbps = 100; /* TO DO: could be 10mbps */ 722 ether->attach = attach; 723 ether->transmit = transmit; 724 ether->interrupt = interrupt; 725 ether->ifstat = ifstat; 726 727 ether->arg = ether; 728 ether->promiscuous = promiscuous; 729 ether->multicast = multicast; 730 731 /* 732 * Until we know where to find it, insist that the plan9.ini 733 * entry holds the Ethernet address. 734 */ 735 memset(ea, 0, Eaddrlen); 736 if(memcmp(ea, ether->ea, Eaddrlen) == 0){ 737 print("no ether address"); 738 return -1; 739 } 740 741 return 0; 742 } 743 744 void 745 etherfcclink(void) 746 { 747 addethercard("fcc", reset); 748 } 749 750 static void 751 nanodelay(void) 752 { 753 static int count; 754 int i; 755 756 for(i = 0; i < 500; i++) 757 count++; 758 return; 759 } 760 761 static 762 void miiwriteloop(Ctlr *ctlr, Port *port, int cnt, ulong cmd) 763 { 764 int i; 765 766 for(i = 0; i < cnt; i++){ 767 port->pdat &= ~ctlr->pmdck; 768 if(cmd & BIT(i)) 769 port->pdat |= ctlr->pmdio; 770 else 771 port->pdat &= ~ctlr->pmdio; 772 nanodelay(); 773 port->pdat |= ctlr->pmdck; 774 nanodelay(); 775 } 776 } 777 778 static int 779 fccmiimiw(Mii *mii, int pa, int ra, int data) 780 { 781 int x; 782 Port *port; 783 ulong cmd; 784 Ctlr *ctlr; 785 786 /* 787 * MII Management Interface Write. 788 */ 789 790 ctlr = mii->ctlr; 791 port = imm->port + 3; 792 cmd = MDIwrite | (pa<<(5+2+16))| (ra<<(2+16)) | (data & 0xffff); 793 794 x = splhi(); 795 796 port->pdir |= (ctlr->pmdio|ctlr->pmdck); 797 nanodelay(); 798 799 miiwriteloop(ctlr, port, 32, ~0); 800 miiwriteloop(ctlr, port, 32, cmd); 801 802 port->pdir |= (ctlr->pmdio|ctlr->pmdck); 803 nanodelay(); 804 805 miiwriteloop(ctlr, port, 32, ~0); 806 807 splx(x); 808 return 1; 809 } 810 811 static int 812 fccmiimir(Mii *mii, int pa, int ra) 813 { 814 int data, i, x; 815 Port *port; 816 ulong cmd; 817 Ctlr *ctlr; 818 819 ctlr = mii->ctlr; 820 port = imm->port + 3; 821 822 cmd = MDIread | pa<<(5+2+16) | ra<<(2+16); 823 824 x = splhi(); 825 port->pdir |= (ctlr->pmdio|ctlr->pmdck); 826 nanodelay(); 827 828 miiwriteloop(ctlr, port, 32, ~0); 829 830 /* Clock out the first 14 MS bits of the command */ 831 miiwriteloop(ctlr, port, 14, cmd); 832 833 /* Turn-around */ 834 port->pdat &= ~ctlr->pmdck; 835 port->pdir &= ~ctlr->pmdio; 836 nanodelay(); 837 838 /* For read, clock in 18 bits, use 16 */ 839 data = 0; 840 for(i=0; i<18; i++){ 841 data <<= 1; 842 if(port->pdat & ctlr->pmdio) 843 data |= 1; 844 port->pdat |= ctlr->pmdck; 845 nanodelay(); 846 port->pdat &= ~ctlr->pmdck; 847 nanodelay(); 848 } 849 port->pdir |= (ctlr->pmdio|ctlr->pmdck); 850 nanodelay(); 851 miiwriteloop(ctlr, port, 32, ~0); 852 splx(x); 853 return data & 0xffff; 854 } 855 856 static void 857 fccltimer(Ureg*, Timer *t) 858 { 859 Ether *ether; 860 Ctlr *ctlr; 861 MiiPhy *phy; 862 ulong gfmr; 863 864 ether = t->ta; 865 ctlr = ether->ctlr; 866 if(ctlr->mii == nil || ctlr->mii->curphy == nil) 867 return; 868 phy = ctlr->mii->curphy; 869 if(miistatus(ctlr->mii) < 0){ 870 print("miistatus failed\n"); 871 return; 872 } 873 if(phy->link == 0){ 874 print("link lost\n"); 875 return; 876 } 877 ether->mbps = phy->speed; 878 879 if(phy->fd != ctlr->duplex) 880 print("set duplex\n"); 881 ilock(ctlr); 882 gfmr = ctlr->fcc->gfmr; 883 if(phy->fd != ctlr->duplex){ 884 ctlr->fcc->gfmr &= ~(ENR|ENT); 885 if(phy->fd) 886 ctlr->fcc->fpsmr |= FDE | LPB; /* full duplex operation */ 887 else 888 ctlr->fcc->fpsmr &= ~(FDE | LPB); /* half duplex operation */ 889 ctlr->duplex = phy->fd; 890 } 891 ctlr->fcc->gfmr = gfmr; 892 iunlock(ctlr); 893 } 894