1 /* 2 * SCCn ethernet 3 */ 4 5 #include "u.h" 6 #include "lib.h" 7 #include "mem.h" 8 #include "dat.h" 9 #include "fns.h" 10 #include "io.h" 11 #include "../port/error.h" 12 #include "../port/netif.h" 13 14 #include "etherif.h" 15 16 enum { 17 Nrdre = 16, /* receive descriptor ring entries */ 18 Ntdre = 16, /* transmit descriptor ring entries */ 19 20 Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */ 21 Bufsize = (Rbsize+7)&~7, /* aligned */ 22 }; 23 24 enum { 25 /* ether-specific Rx BD bits */ 26 RxMiss= 1<<8, 27 RxeLG= 1<<5, 28 RxeNO= 1<<4, 29 RxeSH= 1<<3, 30 RxeCR= 1<<2, 31 RxeOV= 1<<1, 32 RxeCL= 1<<0, 33 RxError= (RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL), /* various error flags */ 34 35 /* ether-specific Tx BD bits */ 36 TxPad= 1<<14, /* pad short frames */ 37 TxTC= 1<<10, /* transmit CRC */ 38 TxeDEF= 1<<9, 39 TxeHB= 1<<8, 40 TxeLC= 1<<7, 41 TxeRL= 1<<6, 42 TxeUN= 1<<1, 43 TxeCSL= 1<<0, 44 45 /* scce */ 46 RXB= 1<<0, 47 TXB= 1<<1, 48 BSY= 1<<2, 49 RXF= 1<<3, 50 TXE= 1<<4, 51 52 /* psmr */ 53 PRO= 1<<9, /* promiscuous mode */ 54 55 /* gsmrl */ 56 ENR= 1<<5, 57 ENT= 1<<4, 58 59 /* port A */ 60 RXD1= SIBIT(15), 61 TXD1= SIBIT(14), 62 63 /* port B */ 64 RTS1= IBIT(19), 65 66 /* port C */ 67 CTS1= SIBIT(11), 68 CD1= SIBIT(10), 69 }; 70 71 typedef struct Etherparam Etherparam; 72 struct Etherparam { 73 SCCparam; 74 ulong c_pres; /* preset CRC */ 75 ulong c_mask; /* constant mask for CRC */ 76 ulong crcec; /* CRC error counter */ 77 ulong alec; /* alighnment error counter */ 78 ulong disfc; /* discard frame counter */ 79 ushort pads; /* short frame PAD characters */ 80 ushort ret_lim; /* retry limit threshold */ 81 ushort ret_cnt; /* retry limit counter */ 82 ushort mflr; /* maximum frame length reg */ 83 ushort minflr; /* minimum frame length reg */ 84 ushort maxd1; /* maximum DMA1 length reg */ 85 ushort maxd2; /* maximum DMA2 length reg */ 86 ushort maxd; /* rx max DMA */ 87 ushort dma_cnt; /* rx dma counter */ 88 ushort max_b; /* max bd byte count */ 89 ushort gaddr[4]; /* group address filter */ 90 ulong tbuf0_data0; /* save area 0 - current frm */ 91 ulong tbuf0_data1; /* save area 1 - current frm */ 92 ulong tbuf0_rba0; 93 ulong tbuf0_crc; 94 ushort tbuf0_bcnt; 95 ushort paddr[3]; /* physical address LSB to MSB increasing */ 96 ushort p_per; /* persistence */ 97 ushort rfbd_ptr; /* rx first bd pointer */ 98 ushort tfbd_ptr; /* tx first bd pointer */ 99 ushort tlbd_ptr; /* tx last bd pointer */ 100 ulong tbuf1_data0; /* save area 0 - next frame */ 101 ulong tbuf1_data1; /* save area 1 - next frame */ 102 ulong tbuf1_rba0; 103 ulong tbuf1_crc; 104 ushort tbuf1_bcnt; 105 ushort tx_len; /* tx frame length counter */ 106 ushort iaddr[4]; /* individual address filter*/ 107 ushort boff_cnt; /* back-off counter */ 108 ushort taddr[3]; /* temp address */ 109 }; 110 111 typedef struct { 112 Lock; 113 int port; 114 int init; 115 int active; 116 SCC* scc; 117 CPMdev* cpm; 118 119 Ring; 120 121 ulong interrupts; /* statistics */ 122 ulong deferred; 123 ulong heartbeat; 124 ulong latecoll; 125 ulong retrylim; 126 ulong underrun; 127 ulong overrun; 128 ulong carrierlost; 129 ulong retrycount; 130 } Ctlr; 131 132 static int sccid[] = {-1, CPscc1, CPscc2, CPscc3, CPscc4}; 133 134 static void 135 attach(Ether *ether) 136 { 137 Ctlr *ctlr; 138 139 ctlr = ether->ctlr; 140 ctlr->active = 1; 141 ctlr->scc->gsmrl |= ENR|ENT; 142 eieio(); 143 } 144 145 static void 146 closed(Ether *ether) 147 { 148 Ctlr *ctlr; 149 150 ctlr = ether->ctlr; 151 if(ctlr->active){ 152 sccxstop(ctlr->cpm); 153 ilock(ctlr); 154 ctlr->active = 0; 155 iunlock(ctlr); 156 } 157 } 158 159 static void 160 promiscuous(void* arg, int on) 161 { 162 Ether *ether; 163 Ctlr *ctlr; 164 165 ether = (Ether*)arg; 166 ctlr = ether->ctlr; 167 168 ilock(ctlr); 169 if(on || ether->nmaddr) 170 ctlr->scc->psmr |= PRO; 171 else 172 ctlr->scc->psmr &= ~PRO; 173 iunlock(ctlr); 174 } 175 176 static void 177 multicast(void* arg, uchar *addr, int on) 178 { 179 Ether *ether; 180 Ctlr *ctlr; 181 182 USED(addr, on); /* if on, could SetGroupAddress; if !on, it's hard */ 183 184 ether = (Ether*)arg; 185 ctlr = ether->ctlr; 186 187 ilock(ctlr); 188 if(ether->prom || ether->nmaddr) 189 ctlr->scc->psmr |= PRO; 190 else 191 ctlr->scc->psmr &= ~PRO; 192 iunlock(ctlr); 193 } 194 195 static void 196 txstart(Ether *ether) 197 { 198 int len; 199 Ctlr *ctlr; 200 Block *b; 201 BD *dre; 202 203 ctlr = ether->ctlr; 204 while(ctlr->ntq < Ntdre-1){ 205 b = qget(ether->oq); 206 if(b == 0) 207 break; 208 209 dre = &ctlr->tdr[ctlr->tdrh]; 210 if(dre->status & BDReady) 211 panic("ether: txstart"); 212 213 /* 214 * Give ownership of the descriptor to the chip, increment the 215 * software ring descriptor pointer and tell the chip to poll. 216 */ 217 len = BLEN(b); 218 dcflush(b->rp, len); 219 if(ctlr->txb[ctlr->tdrh] != nil) 220 panic("scc/ether: txstart"); 221 ctlr->txb[ctlr->tdrh] = b; 222 if((ulong)b->rp&1) 223 panic("scc/ether: txstart align"); /* TO DO: ensure alignment */ 224 dre->addr = PADDR(b->rp); 225 dre->length = len; 226 eieio(); 227 dre->status = (dre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC; 228 eieio(); 229 ctlr->scc->todr = 1<<15; /* transmit now */ 230 eieio(); 231 ctlr->ntq++; 232 ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre); 233 } 234 } 235 236 static void 237 transmit(Ether* ether) 238 { 239 Ctlr *ctlr; 240 241 ctlr = ether->ctlr; 242 ilock(ctlr); 243 txstart(ether); 244 iunlock(ctlr); 245 } 246 247 static void 248 interrupt(Ureg*, void *arg) 249 { 250 Ether *ether; 251 int len, events, status; 252 Ctlr *ctlr; 253 BD *dre; 254 Block *b; 255 256 ether = arg; 257 ctlr = ether->ctlr; 258 if(!ctlr->active) 259 return; /* not ours */ 260 261 /* 262 * Acknowledge all interrupts and whine about those that shouldn't 263 * happen. 264 */ 265 events = ctlr->scc->scce; 266 eieio(); 267 ctlr->scc->scce = events; 268 eieio(); 269 ctlr->interrupts++; 270 271 if(events & (TXE|BSY|RXB)){ 272 if(events & RXB) 273 ctlr->overrun++; 274 if(events & TXE) 275 ether->oerrs++; 276 if(0 || events & TXE) 277 print("ETHER.SCC#%d: scce = 0x%uX\n", ether->ctlrno, events); 278 } 279 /* 280 * Receiver interrupt: run round the descriptor ring logging 281 * errors and passing valid receive data up to the higher levels 282 * until we encounter a descriptor still owned by the chip. 283 */ 284 if(events & (RXF|RXB) || 1){ 285 dre = &ctlr->rdr[ctlr->rdrx]; 286 while(((status = dre->status) & BDEmpty) == 0){ 287 if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ 288 if(status & (RxeLG|RxeSH)) 289 ether->buffs++; 290 if(status & RxeNO) 291 ether->frames++; 292 if(status & RxeCR) 293 ether->crcs++; 294 if(status & RxeOV) 295 ether->overflows++; 296 //print("eth rx: %ux\n", status); 297 } 298 else{ 299 /* 300 * We have a packet. Read it in. 301 */ 302 len = dre->length-4; 303 if((b = iallocb(len)) != 0){ 304 dcinval(KADDR(dre->addr), len); 305 memmove(b->wp, KADDR(dre->addr), len); 306 b->wp += len; 307 etheriq(ether, b, 1); 308 }else 309 ether->soverflows++; 310 } 311 312 /* 313 * Finished with this descriptor, reinitialise it, 314 * give it back to the chip, then on to the next... 315 */ 316 dre->length = 0; 317 dre->status = (status & BDWrap) | BDEmpty | BDInt; 318 eieio(); 319 320 ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre); 321 dre = &ctlr->rdr[ctlr->rdrx]; 322 } 323 } 324 325 /* 326 * Transmitter interrupt: handle anything queued for a free descriptor. 327 */ 328 if(events & TXB){ 329 lock(ctlr); 330 while(ctlr->ntq){ 331 dre = &ctlr->tdr[ctlr->tdri]; 332 status = dre->status; 333 if(status & BDReady) 334 break; 335 if(status & TxeDEF) 336 ctlr->deferred++; 337 if(status & TxeHB) 338 ctlr->heartbeat++; 339 if(status & TxeLC) 340 ctlr->latecoll++; 341 if(status & TxeRL) 342 ctlr->retrylim++; 343 if(status & TxeUN) 344 ctlr->underrun++; 345 if(status & TxeCSL) 346 ctlr->carrierlost++; 347 ctlr->retrycount += (status>>2)&0xF; 348 b = ctlr->txb[ctlr->tdri]; 349 if(b == nil) 350 panic("scce/interrupt: bufp"); 351 ctlr->txb[ctlr->tdri] = nil; 352 freeb(b); 353 ctlr->ntq--; 354 ctlr->tdri = NEXT(ctlr->tdri, Ntdre); 355 } 356 txstart(ether); 357 unlock(ctlr); 358 } 359 if(events & TXE) 360 cpmop(ctlr->cpm, RestartTx, 0); 361 } 362 363 static long 364 ifstat(Ether* ether, void* a, long n, ulong offset) 365 { 366 char *p; 367 int len; 368 Ctlr *ctlr; 369 370 if(n == 0) 371 return 0; 372 373 ctlr = ether->ctlr; 374 375 p = malloc(READSTR); 376 len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); 377 len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); 378 len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); 379 len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); 380 len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount); 381 len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); 382 len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); 383 len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun); 384 snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); 385 n = readstr(offset, a, n, p); 386 free(p); 387 388 return n; 389 } 390 391 /* 392 * This follows the MPC823 user guide: section16.9.23.7's initialisation sequence, 393 * except that it sets the right bits for the MPC823ADS board when SCC2 is used, 394 * and those for the 860/821 development board for SCC1. 395 */ 396 static void 397 sccsetup(Ctlr *ctlr, SCC *scc, Ether *ether) 398 { 399 int i, rcs, tcs, w; 400 Etherparam *p; 401 IMM *io; 402 403 404 i = 2*(ctlr->port-1); 405 io = ioplock(); 406 w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */ 407 io->papar |= w; /* enable TXDn and RXDn pins */ 408 io->padir &= ~w; 409 io->paodr &= ~w; /* not open drain */ 410 411 w = (CD1|CTS1)<<i; /* CLSN and RENA: CDn and CTSn in port C */ 412 io->pcpar &= ~w; /* enable CLSN (CTSn) and RENA (CDn) */ 413 io->pcdir &= ~w; 414 io->pcso |= w; 415 iopunlock(); 416 417 /* clocks and transceiver control: details depend on the board's wiring */ 418 archetherenable(sccid[ctlr->port], &rcs, &tcs, ether->mbps, ether->fullduplex); 419 420 sccnmsi(ctlr->port, rcs, tcs); /* connect the clocks */ 421 422 p = ctlr->cpm->param; 423 memset(p, 0, sizeof(*p)); 424 p->rfcr = 0x18; 425 p->tfcr = 0x18; 426 p->mrblr = Bufsize; 427 p->rbase = PADDR(ctlr->rdr); 428 p->tbase = PADDR(ctlr->tdr); 429 430 cpmop(ctlr->cpm, InitRxTx, 0); 431 432 p->c_pres = ~0; 433 p->c_mask = 0xDEBB20E3; 434 p->crcec = 0; 435 p->alec = 0; 436 p->disfc = 0; 437 p->pads = 0x8888; 438 p->ret_lim = 0xF; 439 p->mflr = Rbsize; 440 p->minflr = ETHERMINTU+4; 441 p->maxd1 = Bufsize; 442 p->maxd2 = Bufsize; 443 p->p_per = 0; /* only moderate aggression */ 444 445 for(i=0; i<Eaddrlen; i+=2) 446 p->paddr[2-i/2] = (ether->ea[i+1]<<8)|ether->ea[i]; /* it's not the obvious byte order */ 447 448 scc->psmr = (2<<10)|(5<<1); /* 32-bit CRC, ignore 22 bits before SFD */ 449 scc->dsr = 0xd555; 450 scc->gsmrh = 0; /* normal operation */ 451 scc->gsmrl = (1<<28)|(4<<21)|(1<<19)|0xC; /* transmit clock invert, 48 bit preamble, repetitive 10 preamble, ethernet */ 452 eieio(); 453 scc->scce = ~0; /* clear all events */ 454 eieio(); 455 scc->sccm = TXE | RXF | TXB; /* enable interrupts */ 456 eieio(); 457 458 io = ioplock(); 459 w = RTS1<<(ctlr->port-1); /* enable TENA pin (RTSn) */ 460 io->pbpar |= w; 461 io->pbdir |= w; 462 iopunlock(); 463 464 /* gsmrl enable is deferred until attach */ 465 } 466 467 static int 468 reset(Ether* ether) 469 { 470 uchar ea[Eaddrlen]; 471 CPMdev *cpm; 472 Ctlr *ctlr; 473 SCC *scc; 474 475 if(m->speed < 24){ 476 print("%s ether: system speed must be >= 24MHz for ether use\n", ether->type); 477 return -1; 478 } 479 480 if(!(ether->port >= 1 && ether->port <= 4)){ 481 print("%s ether: no SCC port %lud\n", ether->type, ether->port); 482 return -1; 483 } 484 485 /* 486 * Insist that the platform-specific code provide the Ethernet address 487 */ 488 memset(ea, 0, Eaddrlen); 489 if(memcmp(ea, ether->ea, Eaddrlen) == 0){ 490 print("no ether address"); 491 return -1; 492 } 493 494 cpm = cpmdev(sccid[ether->port]); 495 if(cpm == nil) 496 return -1; 497 ether->irq = VectorCPIC + cpm->irq; 498 scc = cpm->regs; 499 ctlr = malloc(sizeof(*ctlr)); 500 ether->ctlr = ctlr; 501 memset(ctlr, 0, sizeof(*ctlr)); 502 ctlr->cpm = cpm; 503 ctlr->scc = scc; 504 ctlr->port = ether->port; 505 506 if(ioringinit(ctlr, Nrdre, Ntdre, Bufsize) < 0) 507 panic("etherscc init"); 508 509 sccsetup(ctlr, scc, ether); 510 511 ether->attach = attach; 512 ether->closed = closed; 513 ether->transmit = transmit; 514 ether->interrupt = interrupt; 515 ether->ifstat = ifstat; 516 517 ether->arg = ether; 518 ether->promiscuous = promiscuous; 519 ether->multicast = multicast; 520 521 return 0; 522 } 523 524 void 525 etherscclink(void) 526 { 527 addethercard("SCC", reset); 528 } 529