1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "io.h" 7 #include "pool.h" 8 #include "ureg.h" 9 #include "../port/error.h" 10 #include "../port/netif.h" 11 12 #include "etherif.h" 13 14 static Ether *etherxx[MaxEther]; 15 16 Chan* 17 etherattach(char* spec) 18 { 19 ulong ctlrno; 20 char *p; 21 Chan *chan; 22 23 ctlrno = 0; 24 if(spec && *spec){ 25 ctlrno = strtoul(spec, &p, 0); 26 if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther)) 27 error(Ebadarg); 28 } 29 if(etherxx[ctlrno] == 0) 30 error(Enodev); 31 32 chan = devattach('l', spec); 33 if(waserror()){ 34 chanfree(chan); 35 nexterror(); 36 } 37 chan->dev = ctlrno; 38 if(etherxx[ctlrno]->attach) 39 etherxx[ctlrno]->attach(etherxx[ctlrno]); 40 poperror(); 41 return chan; 42 } 43 44 static Walkqid* 45 etherwalk(Chan* chan, Chan* nchan, char** name, int nname) 46 { 47 return netifwalk(etherxx[chan->dev], chan, nchan, name, nname); 48 } 49 50 static int 51 etherstat(Chan* chan, uchar* dp, int n) 52 { 53 return netifstat(etherxx[chan->dev], chan, dp, n); 54 } 55 56 static Chan* 57 etheropen(Chan* chan, int omode) 58 { 59 return netifopen(etherxx[chan->dev], chan, omode); 60 } 61 62 static void 63 ethercreate(Chan*, char*, int, ulong) 64 { 65 } 66 67 static void 68 etherclose(Chan* chan) 69 { 70 netifclose(etherxx[chan->dev], chan); 71 } 72 73 static long 74 etherread(Chan* chan, void* buf, long n, vlong off) 75 { 76 Ether *ether; 77 ulong offset = off; 78 79 ether = etherxx[chan->dev]; 80 if((chan->qid.type & QTDIR) == 0 && ether->ifstat){ 81 /* 82 * With some controllers it is necessary to reach 83 * into the chip to extract statistics. 84 */ 85 if(NETTYPE(chan->qid.path) == Nifstatqid) 86 return ether->ifstat(ether, buf, n, offset); 87 else if(NETTYPE(chan->qid.path) == Nstatqid) 88 ether->ifstat(ether, buf, 0, offset); 89 } 90 91 return netifread(ether, chan, buf, n, offset); 92 } 93 94 static Block* 95 etherbread(Chan* chan, long n, ulong offset) 96 { 97 return netifbread(etherxx[chan->dev], chan, n, offset); 98 } 99 100 static int 101 etherwstat(Chan* chan, uchar* dp, int n) 102 { 103 return netifwstat(etherxx[chan->dev], chan, dp, n); 104 } 105 106 static void 107 etherrtrace(Netfile* f, Etherpkt* pkt, int len) 108 { 109 int i, n; 110 Block *bp; 111 112 if(qwindow(f->in) <= 0) 113 return; 114 if(len > 58) 115 n = 58; 116 else 117 n = len; 118 bp = iallocb(64); 119 if(bp == nil) 120 return; 121 memmove(bp->wp, pkt->d, n); 122 i = TK2MS(MACHP(0)->ticks); 123 bp->wp[58] = len>>8; 124 bp->wp[59] = len; 125 bp->wp[60] = i>>24; 126 bp->wp[61] = i>>16; 127 bp->wp[62] = i>>8; 128 bp->wp[63] = i; 129 bp->wp += 64; 130 qpass(f->in, bp); 131 } 132 133 Block* 134 etheriq(Ether* ether, Block* bp, int fromwire) 135 { 136 Etherpkt *pkt; 137 ushort type; 138 int len, multi, tome, fromme; 139 Netfile **ep, *f, **fp, *fx; 140 Block *xbp; 141 142 ether->inpackets++; 143 144 pkt = (Etherpkt*)bp->rp; 145 len = BLEN(bp); 146 type = (pkt->type[0]<<8)|pkt->type[1]; 147 fx = 0; 148 ep = ðer->f[Ntypes]; 149 150 multi = pkt->d[0] & 1; 151 /* check for valid multicast addresses */ 152 if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){ 153 if(!activemulti(ether, pkt->d, sizeof(pkt->d))){ 154 if(fromwire){ 155 freeb(bp); 156 bp = 0; 157 } 158 return bp; 159 } 160 } 161 162 /* is it for me? */ 163 tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; 164 fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0; 165 166 /* 167 * Multiplex the packet to all the connections which want it. 168 * If the packet is not to be used subsequently (fromwire != 0), 169 * attempt to simply pass it into one of the connections, thereby 170 * saving a copy of the data (usual case hopefully). 171 */ 172 for(fp = ether->f; fp < ep; fp++){ 173 if(f = *fp) 174 if(f->type == type || f->type < 0) 175 if(tome || multi || f->prom){ 176 /* Don't want to hear bridged packets */ 177 if(f->bridge && !fromwire && !fromme) 178 continue; 179 if(!f->headersonly){ 180 if(fromwire && fx == 0) 181 fx = f; 182 else if(xbp = iallocb(len)){ 183 memmove(xbp->wp, pkt, len); 184 xbp->wp += len; 185 if(qpass(f->in, xbp) < 0) { 186 // print("soverflow for f->in\n"); 187 ether->soverflows++; 188 } 189 } 190 else { 191 // print("soverflow iallocb\n"); 192 ether->soverflows++; 193 } 194 } 195 else 196 etherrtrace(f, pkt, len); 197 } 198 } 199 200 if(fx){ 201 if(qpass(fx->in, bp) < 0) { 202 // print("soverflow for fx->in\n"); 203 ether->soverflows++; 204 } 205 return 0; 206 } 207 if(fromwire){ 208 freeb(bp); 209 return 0; 210 } 211 212 return bp; 213 } 214 215 static int 216 etheroq(Ether* ether, Block* bp) 217 { 218 int len, loopback, s; 219 Etherpkt *pkt; 220 221 ether->outpackets++; 222 223 /* 224 * Check if the packet has to be placed back onto the input queue, 225 * i.e. if it's a loopback or broadcast packet or the interface is 226 * in promiscuous mode. 227 * If it's a loopback packet indicate to etheriq that the data isn't 228 * needed and return, etheriq will pass-on or free the block. 229 * To enable bridging to work, only packets that were originated 230 * by this interface are fed back. 231 */ 232 pkt = (Etherpkt*)bp->rp; 233 len = BLEN(bp); 234 loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; 235 if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){ 236 s = splhi(); 237 etheriq(ether, bp, 0); 238 splx(s); 239 } 240 241 if(!loopback){ 242 if(qfull(ether->oq)) 243 print("etheroq: WARNING: ether->oq full!\n"); 244 qbwrite(ether->oq, bp); 245 if(ether->transmit != nil) 246 ether->transmit(ether); 247 } else 248 freeb(bp); 249 250 return len; 251 } 252 253 static long 254 etherwrite(Chan* chan, void* buf, long n, vlong) 255 { 256 Ether *ether; 257 Block *bp; 258 int nn, onoff; 259 Cmdbuf *cb; 260 261 ether = etherxx[chan->dev]; 262 if(NETTYPE(chan->qid.path) != Ndataqid) { 263 nn = netifwrite(ether, chan, buf, n); 264 if(nn >= 0) 265 return nn; 266 cb = parsecmd(buf, n); 267 if(cb->f[0] && strcmp(cb->f[0], "nonblocking") == 0){ 268 if(cb->nf <= 1) 269 onoff = 1; 270 else 271 onoff = atoi(cb->f[1]); 272 qnoblock(ether->oq, onoff); 273 free(cb); 274 return n; 275 } 276 free(cb); 277 if(ether->ctl!=nil) 278 return ether->ctl(ether,buf,n); 279 280 error(Ebadctl); 281 } 282 283 if(n > ether->maxmtu) 284 error(Etoobig); 285 if(n < ether->minmtu) 286 error(Etoosmall); 287 288 bp = allocb(n); 289 if(waserror()){ 290 freeb(bp); 291 nexterror(); 292 } 293 memmove(bp->rp, buf, n); 294 memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen); 295 poperror(); 296 bp->wp += n; 297 298 return etheroq(ether, bp); 299 } 300 301 static long 302 etherbwrite(Chan* chan, Block* bp, ulong) 303 { 304 Ether *ether; 305 long n; 306 307 n = BLEN(bp); 308 if(NETTYPE(chan->qid.path) != Ndataqid){ 309 if(waserror()) { 310 freeb(bp); 311 nexterror(); 312 } 313 n = etherwrite(chan, bp->rp, n, 0); 314 poperror(); 315 freeb(bp); 316 return n; 317 } 318 ether = etherxx[chan->dev]; 319 320 if(n > ether->maxmtu){ 321 freeb(bp); 322 error(Etoobig); 323 } 324 if(n < ether->minmtu){ 325 freeb(bp); 326 error(Etoosmall); 327 } 328 329 return etheroq(ether, bp); 330 } 331 332 static struct { 333 char* type; 334 int (*reset)(Ether*); 335 } cards[MaxEther+1]; 336 337 void 338 addethercard(char* t, int (*r)(Ether*)) 339 { 340 static int ncard; 341 342 if(ncard == MaxEther) 343 panic("too many ether cards"); 344 cards[ncard].type = t; 345 cards[ncard].reset = r; 346 ncard++; 347 } 348 349 int 350 parseether(uchar *to, char *from) 351 { 352 char nip[4]; 353 char *p; 354 int i; 355 356 p = from; 357 for(i = 0; i < Eaddrlen; i++){ 358 if(*p == 0) 359 return -1; 360 nip[0] = *p++; 361 if(*p == 0) 362 return -1; 363 nip[1] = *p++; 364 nip[2] = 0; 365 to[i] = strtoul(nip, 0, 16); 366 if(*p == ':') 367 p++; 368 } 369 return 0; 370 } 371 372 static Ether* 373 etherprobe(int cardno, int ctlrno) 374 { 375 int i, lg; 376 ulong mb, bsz; 377 Ether *ether; 378 char buf[128], name[32]; 379 380 ether = malloc(sizeof(Ether)); 381 memset(ether, 0, sizeof(Ether)); 382 ether->ctlrno = ctlrno; 383 ether->tbdf = BUSUNKNOWN; 384 ether->mbps = 10; 385 ether->minmtu = ETHERMINTU; 386 ether->maxmtu = ETHERMAXTU; 387 388 if(cardno < 0){ 389 if(isaconfig("ether", ctlrno, ether) == 0){ 390 free(ether); 391 return nil; 392 } 393 for(cardno = 0; cards[cardno].type; cardno++){ 394 if(cistrcmp(cards[cardno].type, ether->type)) 395 continue; 396 for(i = 0; i < ether->nopt; i++){ 397 if(strncmp(ether->opt[i], "ea=", 3)) 398 continue; 399 if(parseether(ether->ea, ðer->opt[i][3])) 400 memset(ether->ea, 0, Eaddrlen); 401 } 402 break; 403 } 404 } 405 406 if(cardno >= MaxEther || cards[cardno].type == nil){ 407 free(ether); 408 return nil; 409 } 410 if(cards[cardno].reset(ether) < 0){ 411 free(ether); 412 return nil; 413 } 414 415 /* 416 * IRQ2 doesn't really exist, it's used to gang the interrupt 417 * controllers together. A device set to IRQ2 will appear on 418 * the second interrupt controller as IRQ9. 419 */ 420 if(ether->irq == 2) 421 ether->irq = 9; 422 snprint(name, sizeof(name), "ether%d", ctlrno); 423 424 /* 425 * If ether->irq is <0, it is a hack to indicate no interrupt 426 * used by ethersink. 427 */ 428 if(ether->irq >= 0) 429 intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name); 430 431 i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d", 432 ctlrno, cards[cardno].type, ether->mbps, ether->port, ether->irq); 433 if(ether->mem) 434 i += sprint(buf+i, " addr 0x%luX", ether->mem); 435 if(ether->size) 436 i += sprint(buf+i, " size 0x%luX", ether->size); 437 i += sprint(buf+i, ": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux", 438 ether->ea[0], ether->ea[1], ether->ea[2], 439 ether->ea[3], ether->ea[4], ether->ea[5]); 440 sprint(buf+i, "\n"); 441 print(buf); 442 443 /* compute log10(ether->mbps) into lg */ 444 for(lg = 0, mb = ether->mbps; mb >= 10; lg++) 445 mb /= 10; 446 if (lg > 0) 447 lg--; 448 if (lg > 14) /* 2^(14+17) = 2ⁱ */ 449 lg = 14; 450 /* allocate larger output queues for higher-speed interfaces */ 451 bsz = 1UL << (lg + 17); /* 2ⁱ⁷ = 128K, bsz = 2ⁿ × 128K */ 452 while (bsz > mainmem->maxsize / 8 && bsz > 128*1024) 453 bsz /= 2; 454 455 netifinit(ether, name, Ntypes, bsz); 456 if(ether->oq == nil) { 457 ether->oq = qopen(bsz, Qmsg, 0, 0); 458 ether->limit = bsz; 459 } 460 if(ether->oq == nil) 461 panic("etherreset %s: can't allocate output queue of %ld bytes", 462 name, bsz); 463 ether->alen = Eaddrlen; 464 memmove(ether->addr, ether->ea, Eaddrlen); 465 memset(ether->bcast, 0xFF, Eaddrlen); 466 467 return ether; 468 } 469 470 static void 471 etherreset(void) 472 { 473 Ether *ether; 474 int cardno, ctlrno; 475 476 for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){ 477 if((ether = etherprobe(-1, ctlrno)) == nil) 478 continue; 479 etherxx[ctlrno] = ether; 480 } 481 482 if(getconf("*noetherprobe")) 483 return; 484 485 cardno = ctlrno = 0; 486 while(cards[cardno].type != nil && ctlrno < MaxEther){ 487 if(etherxx[ctlrno] != nil){ 488 ctlrno++; 489 continue; 490 } 491 if((ether = etherprobe(cardno, ctlrno)) == nil){ 492 cardno++; 493 continue; 494 } 495 etherxx[ctlrno] = ether; 496 ctlrno++; 497 } 498 } 499 500 static void 501 ethershutdown(void) 502 { 503 Ether *ether; 504 int i; 505 506 for(i = 0; i < MaxEther; i++){ 507 ether = etherxx[i]; 508 if(ether == nil) 509 continue; 510 if(ether->shutdown == nil) { 511 print("#l%d: no shutdown fuction\n", i); 512 continue; 513 } 514 (*ether->shutdown)(ether); 515 } 516 } 517 518 519 #define POLY 0xedb88320 520 521 /* really slow 32 bit crc for ethers */ 522 ulong 523 ethercrc(uchar *p, int len) 524 { 525 int i, j; 526 ulong crc, b; 527 528 crc = 0xffffffff; 529 for(i = 0; i < len; i++){ 530 b = *p++; 531 for(j = 0; j < 8; j++){ 532 crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0); 533 b >>= 1; 534 } 535 } 536 return crc; 537 } 538 539 Dev etherdevtab = { 540 'l', 541 "ether", 542 543 etherreset, 544 devinit, 545 ethershutdown, 546 etherattach, 547 etherwalk, 548 etherstat, 549 etheropen, 550 ethercreate, 551 etherclose, 552 etherread, 553 etherbread, 554 etherwrite, 555 etherbwrite, 556 devremove, 557 etherwstat, 558 }; 559