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 12 #include "etherif.h" 13 14 enum { 15 Nrdre = 32, /* receive descriptor ring entries */ 16 Ntdre = 4, /* transmit descriptor ring entries */ 17 18 Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */ 19 Bufsize = (Rbsize+7)&~7, /* aligned */ 20 }; 21 22 enum { 23 /* ether-specific Rx BD bits */ 24 RxMiss= 1<<8, 25 RxeLG= 1<<5, 26 RxeNO= 1<<4, 27 RxeSH= 1<<3, 28 RxeCR= 1<<2, 29 RxeOV= 1<<1, 30 RxeCL= 1<<0, 31 RxError= (RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL), /* various error flags */ 32 33 /* ether-specific Tx BD bits */ 34 TxPad= 1<<14, /* pad short frames */ 35 TxTC= 1<<10, /* transmit CRC */ 36 TxeDEF= 1<<9, 37 TxeHB= 1<<8, 38 TxeLC= 1<<7, 39 TxeRL= 1<<6, 40 TxeUN= 1<<1, 41 TxeCSL= 1<<0, 42 43 /* scce */ 44 RXB= 1<<0, 45 TXB= 1<<1, 46 BSY= 1<<2, 47 RXF= 1<<3, 48 TXE= 1<<4, 49 50 /* gsmrl */ 51 ENR= 1<<5, 52 ENT= 1<<4, 53 54 /* port A */ 55 RXD1= SIBIT(15), 56 TXD1= SIBIT(14), 57 58 /* port B */ 59 RTS1= IBIT(19), 60 61 /* port C */ 62 CTS1= SIBIT(11), 63 CD1= SIBIT(10), 64 }; 65 66 typedef struct Etherparam Etherparam; 67 struct Etherparam { 68 SCCparam; 69 ulong c_pres; /* preset CRC */ 70 ulong c_mask; /* constant mask for CRC */ 71 ulong crcec; /* CRC error counter */ 72 ulong alec; /* alighnment error counter */ 73 ulong disfc; /* discard frame counter */ 74 ushort pads; /* short frame PAD characters */ 75 ushort ret_lim; /* retry limit threshold */ 76 ushort ret_cnt; /* retry limit counter */ 77 ushort mflr; /* maximum frame length reg */ 78 ushort minflr; /* minimum frame length reg */ 79 ushort maxd1; /* maximum DMA1 length reg */ 80 ushort maxd2; /* maximum DMA2 length reg */ 81 ushort maxd; /* rx max DMA */ 82 ushort dma_cnt; /* rx dma counter */ 83 ushort max_b; /* max bd byte count */ 84 ushort gaddr[4]; /* group address filter */ 85 ulong tbuf0_data0; /* save area 0 - current frm */ 86 ulong tbuf0_data1; /* save area 1 - current frm */ 87 ulong tbuf0_rba0; 88 ulong tbuf0_crc; 89 ushort tbuf0_bcnt; 90 ushort paddr[3]; /* physical address LSB to MSB increasing */ 91 ushort p_per; /* persistence */ 92 ushort rfbd_ptr; /* rx first bd pointer */ 93 ushort tfbd_ptr; /* tx first bd pointer */ 94 ushort tlbd_ptr; /* tx last bd pointer */ 95 ulong tbuf1_data0; /* save area 0 - next frame */ 96 ulong tbuf1_data1; /* save area 1 - next frame */ 97 ulong tbuf1_rba0; 98 ulong tbuf1_crc; 99 ushort tbuf1_bcnt; 100 ushort tx_len; /* tx frame length counter */ 101 ushort iaddr[4]; /* individual address filter*/ 102 ushort boff_cnt; /* back-off counter */ 103 ushort taddr[3]; /* temp address */ 104 }; 105 106 typedef struct { 107 SCC* scc; 108 int port; 109 int cpm; 110 111 BD* rdr; /* receive descriptor ring */ 112 void* rrb; /* receive ring buffers */ 113 int rdrx; /* index into rdr */ 114 115 BD* tdr; /* transmit descriptor ring */ 116 void* trb; /* transmit ring buffers */ 117 int tdrx; /* index into tdr */ 118 } Mot; 119 static Mot mot[MaxEther]; 120 121 static int sccid[] = {-1, SCC1ID, SCC2ID, SCC3ID, SCC4ID}; 122 static int sccparam[] = {-1, SCC1P, SCC2P, SCC3P, SCC4P}; 123 static int sccreg[] = {-1, 0xA00, 0xA20, 0xA40, 0xA60}; 124 static int sccirq[] = {-1, 0x1E, 0x1D, 0x1C, 0x1B}; 125 126 static void 127 attach(Ctlr *ctlr) 128 { 129 mot[ctlr->ctlrno].scc->gsmrl |= ENR|ENT; 130 eieio(); 131 } 132 133 static void 134 transmit(Ctlr *ctlr) 135 { 136 int len; 137 Mot *motp; 138 Block *b; 139 BD *tdre; 140 141 motp = &mot[ctlr->ctlrno]; 142 while(((tdre = &motp->tdr[motp->tdrx])->status & BDReady) == 0){ 143 b = qget(ctlr->oq); 144 if(b == 0) 145 break; 146 147 /* 148 * Copy the packet to the transmit buffer. 149 */ 150 len = BLEN(b); 151 memmove(KADDR(tdre->addr), b->rp, len); 152 153 /* 154 * Give ownership of the descriptor to the chip, increment the 155 * software ring descriptor pointer and tell the chip to poll. 156 */ 157 tdre->length = len; 158 eieio(); 159 tdre->status = (tdre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC; 160 eieio(); 161 motp->scc->todr = 1<<15; /* transmit now */ 162 eieio(); 163 motp->tdrx = NEXT(motp->tdrx, Ntdre); 164 165 freeb(b); 166 167 } 168 } 169 170 static void 171 interrupt(Ureg*, void *ap) 172 { 173 int len, events, status; 174 Mot *motp; 175 BD *rdre; 176 Block *b; 177 Ctlr *ctlr; 178 179 ctlr = ap; 180 motp = &mot[ctlr->ctlrno]; 181 182 /* 183 * Acknowledge all interrupts and whine about those that shouldn't 184 * happen. 185 */ 186 events = motp->scc->scce; 187 eieio(); 188 motp->scc->scce = events; 189 eieio(); 190 if(events & (TXE|BSY|RXB)) 191 print("ETHER.SCC#%d: scce = 0x%uX\n", ctlr->ctlrno, events); 192 //print(" %ux|", events); 193 /* 194 * Receiver interrupt: run round the descriptor ring logging 195 * errors and passing valid receive data up to the higher levels 196 * until we encounter a descriptor still owned by the chip. 197 */ 198 if(events & (RXF|RXB) || 1){ 199 rdre = &motp->rdr[motp->rdrx]; 200 while(((status = rdre->status) & BDEmpty) == 0){ 201 if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ 202 //if(status & RxBuff) 203 // ctlr->buffs++; 204 if(status & (1<<2)) 205 ctlr->crcs++; 206 if(status & (1<<1)) 207 ctlr->overflows++; 208 //print("eth rx: %ux\n", status); 209 if(status & RxError) 210 print("~"); 211 else if((status & BDLast) == 0) 212 print("@"); 213 } 214 else{ 215 /* 216 * We have a packet. Read it into the next 217 * free ring buffer, if any. 218 */ 219 len = rdre->length-4; 220 if((b = iallocb(len)) != 0){ 221 memmove(b->wp, KADDR(rdre->addr), len); 222 b->wp += len; 223 etheriq(ctlr, b, 1); 224 } 225 } 226 227 /* 228 * Finished with this descriptor, reinitialise it, 229 * give it back to the chip, then on to the next... 230 */ 231 rdre->length = 0; 232 rdre->status = (rdre->status & BDWrap) | BDEmpty | BDInt; 233 eieio(); 234 235 motp->rdrx = NEXT(motp->rdrx, Nrdre); 236 rdre = &motp->rdr[motp->rdrx]; 237 } 238 } 239 240 /* 241 * Transmitter interrupt: handle anything queued for a free descriptor. 242 */ 243 if(events & TXB) 244 transmit(ctlr); 245 if(events & TXE) 246 cpmop(RestartTx, motp->cpm, 0); 247 } 248 249 static void 250 ringinit(Mot* motp) 251 { 252 int i, x; 253 254 /* 255 * Initialise the receive and transmit buffer rings. The ring 256 * entries must be aligned on 16-byte boundaries. 257 */ 258 if(motp->rdr == 0) 259 motp->rdr = bdalloc(Nrdre); 260 if(motp->rrb == 0) 261 motp->rrb = ialloc(Nrdre*Bufsize, 0); 262 x = PADDR(motp->rrb); 263 for(i = 0; i < Nrdre; i++){ 264 motp->rdr[i].length = 0; 265 motp->rdr[i].addr = x; 266 motp->rdr[i].status = BDEmpty|BDInt; 267 x += Bufsize; 268 } 269 motp->rdr[i-1].status |= BDWrap; 270 motp->rdrx = 0; 271 272 if(motp->tdr == 0) 273 motp->tdr = bdalloc(Ntdre); 274 if(motp->trb == 0) 275 motp->trb = ialloc(Ntdre*Bufsize, 0); 276 x = PADDR(motp->trb); 277 for(i = 0; i < Ntdre; i++){ 278 motp->tdr[i].addr = x; 279 motp->tdr[i].length = 0; 280 motp->tdr[i].status = TxPad|BDInt|BDLast|TxTC; 281 x += Bufsize; 282 } 283 motp->tdr[i-1].status |= BDWrap; 284 motp->tdrx = 0; 285 } 286 287 /* 288 * This follows the MPC823 user guide: section16.9.23.7's initialisation sequence, 289 * except that it sets the right bits for the MPC823ADS board when SCC2 is used, 290 * and those for the 860/821 development board for SCC1. 291 */ 292 static void 293 sccsetup(Mot *ctlr, SCC *scc, uchar *ea) 294 { 295 int i, rcs, tcs, w; 296 Etherparam *p; 297 IMM *io; 298 299 300 i = 2*(ctlr->port-1); 301 io = ioplock(); 302 w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */ 303 io->papar |= w; /* enable TXDn and RXDn pins */ 304 io->padir &= ~w; 305 io->paodr &= ~w; /* not open drain */ 306 307 w = (CD1|CTS1)<<i; /* CLSN and RENA: CDn and CTSn in port C */ 308 io->pcpar &= ~w; /* enable CLSN (CTSn) and RENA (CDn) */ 309 io->pcdir &= ~w; 310 io->pcso |= w; 311 iopunlock(); 312 313 /* clocks and transceiver control: details depend on the board's wiring */ 314 archetherenable(ctlr->cpm, &rcs, &tcs); 315 316 sccnmsi(ctlr->port, rcs, tcs); /* connect the clocks */ 317 318 p = (Etherparam*)KADDR(sccparam[ctlr->port]); 319 memset(p, 0, sizeof(*p)); 320 p->rfcr = 0x18; 321 p->tfcr = 0x18; 322 p->mrblr = Bufsize; 323 p->rbase = PADDR(ctlr->rdr); 324 p->tbase = PADDR(ctlr->tdr); 325 326 cpmop(InitRxTx, ctlr->cpm, 0); 327 328 p->c_pres = ~0; 329 p->c_mask = 0xDEBB20E3; 330 p->crcec = 0; 331 p->alec = 0; 332 p->disfc = 0; 333 p->pads = 0x8888; 334 p->ret_lim = 0xF; 335 p->mflr = Rbsize; 336 p->minflr = ETHERMINTU+4; 337 p->maxd1 = Bufsize; 338 p->maxd2 = Bufsize; 339 p->p_per = 0; /* only moderate aggression */ 340 341 for(i=0; i<Eaddrlen; i+=2) 342 p->paddr[2-i/2] = (ea[i+1]<<8)|ea[i]; /* it's not the obvious byte order */ 343 344 scc->psmr = (2<<10)|(5<<1); /* 32-bit CRC, ignore 22 bits before SFD */ 345 scc->dsr = 0xd555; 346 scc->gsmrh = 0; /* normal operation */ 347 scc->gsmrl = (1<<28)|(4<<21)|(1<<19)|0xC; /* transmit clock invert, 48 bit preamble, repetitive 10 preamble, ethernet */ 348 eieio(); 349 scc->scce = ~0; /* clear all events */ 350 eieio(); 351 scc->sccm = TXE | RXF | TXB; /* enable interrupts */ 352 eieio(); 353 354 io = ioplock(); 355 w = RTS1<<(ctlr->port-1); /* enable TENA pin (RTSn) */ 356 io->pbpar |= w; 357 io->pbdir |= w; 358 iopunlock(); 359 360 /* gsmrl enable is deferred until attach */ 361 } 362 363 /* 364 * Prepare the SCCx ethernet for booting. 365 */ 366 int 367 sccethreset(Ctlr* ctlr) 368 { 369 uchar ea[Eaddrlen]; 370 Mot *motp; 371 SCC *scc; 372 char line[50], def[50]; 373 374 /* 375 * Since there's no EPROM, insist that the configuration entry 376 * (see conf.c and flash.c) holds the Ethernet address. 377 */ 378 memset(ea, 0, Eaddrlen); 379 if(memcmp(ea, ctlr->card.ea, Eaddrlen) == 0){ 380 print("no preset Ether address\n"); 381 for(;;){ 382 strcpy(def, "00108bf12900"); /* valid MAC address to be used only for initial configuration */ 383 if(getstr("ether MAC address", line, sizeof(line), def) < 0) 384 return -1; 385 if(parseether(ctlr->card.ea, line) >= 0 || ctlr->card.ea[0] == 0xFF) 386 break; 387 print("invalid MAC address\n"); 388 } 389 } 390 391 scc = IOREGS(sccreg[ctlr->card.port], SCC); 392 ctlr->card.irq = VectorCPIC+sccirq[ctlr->card.port]; 393 394 motp = &mot[ctlr->ctlrno]; 395 motp->scc = scc; 396 motp->port = ctlr->card.port; 397 motp->cpm = sccid[ctlr->card.port]; 398 399 ringinit(motp); 400 401 sccsetup(motp, scc, ctlr->card.ea); 402 403 /* enable is deferred until attach */ 404 405 ctlr->card.reset = sccethreset; 406 ctlr->card.attach = attach; 407 ctlr->card.transmit = transmit; 408 ctlr->card.intr = interrupt; 409 410 return 0; 411 } 412