2 #include "../port/lib.h"
8 #include "../port/error.h"
9 #include "../port/netif.h"
13 static volatile Ether *etherxx[MaxEther];
21 addethercard(char* t, int (*r)(Ether*))
26 panic("too many ether cards");
27 cards[ncard].type = t;
28 cards[ncard].reset = r;
37 /* Power all ether cards on or off */
39 iprint("etherpower %d\n", on);
40 for (i = 0; i < MaxEther; i++){
41 if ((ether = etherxx[i]) == nil)
44 if (ether->writer == 0){
45 print("etherpower: already powered up\n");
49 ether->power(ether, on);
51 /* Unlock when power restored */
53 if (ether->writer != 0){
54 print("etherpower: already powered down\n");
57 /* Keep locked until power goes back on */
60 ether->power(ether, on);
66 etherconfig(int on, char *spec, DevConf *cf)
70 char name[32], buf[128];
74 sprint(name, "ether%d", ctlrno);
79 if(etherxx[ctlrno] != nil)
82 ether = malloc(sizeof(Ether));
87 for(n = 0; cards[n].type; n++){
88 if(strcmp(cards[n].type, ether->type) != 0)
90 if(cards[n].reset(ether))
93 if(ether->mbps >= 100){
94 netifinit(ether, name, Ntypes, 256*1024);
96 ether->oq = qopen(256*1024, Qmsg, 0, 0);
99 netifinit(ether, name, Ntypes, 65*1024);
101 ether->oq = qopen(65*1024, Qmsg, 0, 0);
104 panic("etherreset %s", name);
105 ether->alen = Eaddrlen;
106 memmove(ether->addr, ether->ea, Eaddrlen);
107 memset(ether->bcast, 0xFF, Eaddrlen);
109 ether->minmtu = ETHERMINTU;
110 ether->maxmtu = ETHERMAXTU;
112 if(ether->interrupt != nil)
113 intrenable(cf->itype, cf->intnum, ether->interrupt, ether, name);
117 p = seprint(p, e, "#l%d: %s: %dMbps port 0x%luX",
118 ctlrno, ether->type, ether->mbps, ether->ports[0].port);
120 p = seprint(p, e, " addr 0x%luX", PADDR(ether->mem));
121 if(ether->ports[0].size)
122 p = seprint(p, e, " size 0x%X", ether->ports[0].size);
123 p = seprint(p, e, ": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
124 ether->ea[0], ether->ea[1], ether->ea[2],
125 ether->ea[3], ether->ea[4], ether->ea[5]);
129 etherxx[ctlrno] = ether;
140 etherattach(char* spec)
149 ctlrno = strtoul(spec, &p, 0);
150 if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther))
153 if((ether = etherxx[ctlrno]) == 0)
160 chan = devattach('l', spec);
163 ether->attach(ether);
170 etherwalk(Chan* chan, Chan* nchan, char** name, int nname)
175 ether = etherxx[chan->dev];
181 q = netifwalk(ether, chan, nchan, name, nname);
188 etherstat(Chan* chan, uchar* dp, int n)
193 ether = etherxx[chan->dev];
199 s = netifstat(ether, chan, dp, n);
206 etheropen(Chan* chan, int omode)
211 ether = etherxx[chan->dev];
217 c = netifopen(ether, chan, omode);
224 ethercreate(Chan*, char*, int, ulong)
229 etherclose(Chan* chan)
233 ether = etherxx[chan->dev];
239 netifclose(ether, chan);
245 etherread(Chan* chan, void* buf, long n, vlong off)
251 ether = etherxx[chan->dev];
257 if((chan->qid.type & QTDIR) == 0 && ether->ifstat){
259 * With some controllers it is necessary to reach
260 * into the chip to extract statistics.
262 if(NETTYPE(chan->qid.path) == Nifstatqid){
263 r = ether->ifstat(ether, buf, n, offset);
266 if(NETTYPE(chan->qid.path) == Nstatqid)
267 ether->ifstat(ether, buf, 0, offset);
269 r = netifread(ether, chan, buf, n, offset);
277 etherbread(Chan* chan, long n, ulong offset)
282 ether = etherxx[chan->dev];
288 b = netifbread(ether, chan, n, offset);
295 etherwstat(Chan* chan, uchar* dp, int n)
300 ether = etherxx[chan->dev];
306 r = netifwstat(ether, chan, dp, n);
313 etherrtrace(Netfile* f, Etherpkt* pkt, int len)
318 if(qwindow(f->in) <= 0)
327 memmove(bp->wp, pkt->d, n);
328 i = TK2MS(MACHP(0)->ticks);
340 etheriq(Ether* ether, Block* bp, int fromwire)
344 int len, multi, tome, fromme;
345 Netfile **ep, *f, **fp, *fx;
350 pkt = (Etherpkt*)bp->rp;
352 type = (pkt->type[0]<<8)|pkt->type[1];
354 ep = ðer->f[Ntypes];
356 multi = pkt->d[0] & 1;
357 /* check for valid multicast addresses */
358 if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){
359 if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
369 tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
370 fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;
373 * Multiplex the packet to all the connections which want it.
374 * If the packet is not to be used subsequently (fromwire != 0),
375 * attempt to simply pass it into one of the connections, thereby
376 * saving a copy of the data (usual case hopefully).
378 for(fp = ether->f; fp < ep; fp++){
380 if(f->type == type || f->type < 0)
381 if(tome || multi || f->prom){
382 /* Don't want to hear bridged packets */
383 if(f->bridge && !fromwire && !fromme)
386 if(fromwire && fx == 0)
388 else if(xbp = iallocb(len)){
389 memmove(xbp->wp, pkt, len);
397 etherrtrace(f, pkt, len);
402 if(qpass(fx->in, bp) < 0)
415 etheroq(Ether* ether, Block* bp)
417 int len, loopback, s;
423 * Check if the packet has to be placed back onto the input queue,
424 * i.e. if it's a loopback or broadcast packet or the interface is
425 * in promiscuous mode.
426 * If it's a loopback packet indicate to etheriq that the data isn't
427 * needed and return, etheriq will pass-on or free the block.
428 * To enable bridging to work, only packets that were originated
429 * by this interface are fed back.
431 pkt = (Etherpkt*)bp->rp;
433 loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
434 if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
436 etheriq(ether, bp, 0);
441 qbwrite(ether->oq, bp);
442 ether->transmit(ether);
450 etherwrite(Chan* chan, void* buf, long n, vlong)
456 ether = etherxx[chan->dev];
462 if(NETTYPE(chan->qid.path) != Ndataqid) {
463 l = netifwrite(ether, chan, buf, n);
466 if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){
467 qnoblock(ether->oq, 1);
471 l = ether->ctl(ether,buf,n);
477 if(n > ether->maxmtu)
479 if(n < ether->minmtu)
482 memmove(bp->rp, buf, n);
483 memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
486 l = etheroq(ether, bp);
494 etherbwrite(Chan* chan, Block* bp, ulong)
500 if(NETTYPE(chan->qid.path) != Ndataqid){
505 n = etherwrite(chan, bp->rp, n, 0);
510 ether = etherxx[chan->dev];
516 if(n > ether->maxmtu){
520 if(n < ether->minmtu){
524 n = etheroq(ether, bp);
531 parseether(uchar *to, char *from)
538 for(i = 0; i < 6; i++){
546 to[i] = strtoul(nip, 0, 16);
558 #define POLY 0xedb88320
560 /* really slow 32 bit crc for ethers */
562 ethercrc(uchar *p, int len)
568 for(i = 0; i < len; i++){
570 for(j = 0; j < 8; j++){
571 crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0);