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