From 5f040733c35c1597a135df3d5882e80df846aa9a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 15 Apr 1997 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1997-04-15 --- pc/devether.c | 22 +++++++++++++++++++ pc/ether8390.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ pc/ether8390.h | 2 ++ pc/etherelnk3.c | 4 +++- pc/etherif.h | 1 + pc/fns.h | 3 +-- port/portfns.h | 1 - 7 files changed, 85 insertions(+), 4 deletions(-) diff --git a/pc/devether.c b/pc/devether.c index cc1c555e96c38e9ee44c0c7aea5683e6cf775a7d..138c937b7799385539465e2c696d6dc830c1f3ad 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -385,6 +385,28 @@ etherreset(void) free(ether); } +#define POLY 0xedb88320 + +/* really slow 32 bit crc for ethers */ +ulong +ethercrc(uchar *p, int len) +{ + int i, j; + ulong crc, b; + + crc = 0xffffffff; + for(i = 0; i < len; i++){ + b = *p++; + for(j = 0; j < 8; j++){ + crc = (crc>>1); + if((crc^b) & 1) + crc ^= POLY; + b >>= 1; + } + } + return crc; +} + Dev etherdevtab = { 'l', "ether", diff --git a/pc/ether8390.c b/pc/ether8390.c index ac88802c71e9b62b36f2fcb1b0fe547101d15265..1eb53a5536633f500d0e4385ec02b8406adee789 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -620,6 +620,59 @@ promiscuous(void *arg, int on) r = Ab; if(on) r |= Pro; + if(ether->nmaddr) + r |= Am; + ilock(ctlr); + regw(ctlr, Rcr, r); + iunlock(ctlr); +} + +static void +multicast(void* arg, uchar *addr, int on) +{ + Ether *ether; + Dp8390 *ctlr; + uchar r, cr; + int i; + ulong h; + + USED(addr, on); + + ether = arg; + ctlr = ether->ctlr; + + /* + * change filter bits + */ + h = ethercrc(addr, 6); + h = h>>(32-6); + i = h/8; + h = h%8; + ilock(ctlr); + cr = regr(ctlr, Cr) & ~Txp; + regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr)); + r = regr(ctlr, Mar0+i); + if(on){ + if(++(ctlr->mref[h]) == 1) + r |= 1<mref[h]) <= 0){ + ctlr->mref[h] = 0; + r &= ~(1<nmaddr) + r |= Am; + if(ether->prom) + r |= Pro; ilock(ctlr); regw(ctlr, Rcr, r); iunlock(ctlr); @@ -642,6 +695,8 @@ attach(Ether* ether) r = Ab; if(ether->prom) r |= Pro; + if(ether->nmaddr) + r |= Am; ilock(ctlr); regw(ctlr, Rcr, r); r = regr(ctlr, Cntr2); @@ -719,6 +774,7 @@ dp8390reset(Ether* ether) ether->ifstat = 0; ether->promiscuous = promiscuous; + ether->multicast = multicast; ether->arg = ether; return 0; diff --git a/pc/ether8390.h b/pc/ether8390.h index 1c464110988693b0ffb7c8142373b1ae1c105361..8fff39432a14275a36fff9be9eb061b0042e4cd6 100644 --- a/pc/ether8390.h +++ b/pc/ether8390.h @@ -19,6 +19,8 @@ typedef struct { int txbusy; /* transmit */ uchar tstart; /* 8390 ring addresses */ + + int mref[64]; /* reference counts for multicast groups */ } Dp8390; #define Dp8390BufSz 256 diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 7459de517746e7710efc882dec5e78442b48725a..a87f486aa11020d685d915554c5b09e56f32308b 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -467,10 +467,12 @@ multicast(void* arg, uchar *addr, int on) ether = (Ether*)arg; port = ether->port; -print("mutlicast nmaddr == %d\n", ether->nmaddr); +print("multicast nmaddr == %d\n", ether->nmaddr); filter = receiveBroadcast|receiveIndividual; if(ether->nmaddr) filter |= receiveMulticast; + if(ether->prom) + filter |= receiveAllFrames; COMMAND(port, SetRxFilter, filter); } diff --git a/pc/etherif.h b/pc/etherif.h index 97f65bdfa7cb8fd57eba411f834b075ce94b4652..cc82e05e5f8dd731866e208b63d8bb11970d1404 100644 --- a/pc/etherif.h +++ b/pc/etherif.h @@ -24,6 +24,7 @@ struct Ether { extern Block* etheriq(Ether*, Block*, int); extern void addethercard(char*, int(*)(Ether*)); +extern ulong ethercrc(uchar*, int); #define NEXT(x, l) (((x)+1)%(l)) #define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) diff --git a/pc/fns.h b/pc/fns.h index 2e747514ac0e4358b1e7b3aab550a663123b0faa..766c28d7cedadd78bd81f9704eb47294c2895b54 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -48,11 +48,10 @@ void insl(int, void*, int); void intrenable(int, void (*)(Ureg*, void*), void*, int); int iprint(char*, ...); int isaconfig(char*, int, ISAConf*); -ulong getisa(ulong, int, int); -void putisa(ulong, int); void kbdinit(void); void lgdt(ushort[3]); void lidt(ushort[3]); +void links(void); void ltr(ulong); void mathinit(void); #define mmuflushtlb(pdb) putcr3(pdb) diff --git a/port/portfns.h b/port/portfns.h index 50d7bdbe7ae6ca894744e493fd38e53b029b53ca..33d5a596b83051e7a6fe5217861f18b646422754 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -135,7 +135,6 @@ void kprocchild(Proc*, void (*)(void*), void*); void (*kproftimer)(ulong); void ksetenv(char*, char*); long latin1(uchar*, int); -void links(void); void lock(Lock*); void lockinit(void); Page* lookpage(Image*, ulong);