Browse Source

Plan 9 from Bell Labs 2007-07-29

David du Colombier 16 years ago
parent
commit
1012209c84

+ 4 - 4
dist/replica/_plan9.db

@@ -8044,8 +8044,8 @@ sys/src/9/pc/ether2114x.c - 664 sys sys 1184468570 41707
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1160070602 14088
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
-sys/src/9/pc/ether8139.c - 664 sys sys 1185509068 18584
-sys/src/9/pc/ether8169.c - 664 sys sys 1185509068 25466
+sys/src/9/pc/ether8139.c - 664 sys sys 1185650567 19974
+sys/src/9/pc/ether8169.c - 664 sys sys 1185650568 26932
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1131290377 32294
 sys/src/9/pc/ether82557.c - 664 sys sys 1185509068 30197
 sys/src/9/pc/ether82563.c - 664 sys sys 1178932992 32729
@@ -8055,7 +8055,7 @@ sys/src/9/pc/ether8390.h - 664 sys sys 1015014517 1511
 sys/src/9/pc/etherdp83820.c - 664 sys sys 1184468435 29621
 sys/src/9/pc/etherec2t.c - 664 sys sys 1135784135 4092
 sys/src/9/pc/etherelnk3.c - 664 sys sys 1158012427 48807
-sys/src/9/pc/etherga620.c - 664 sys sys 1175322931 29912
+sys/src/9/pc/etherga620.c - 664 sys sys 1185652495 29895
 sys/src/9/pc/etherga620fw.h - 664 sys sys 1026847642 222295
 sys/src/9/pc/etherif.h - 664 sys sys 1088178711 961
 sys/src/9/pc/etherigbe.c - 664 sys sys 1184468343 44976
@@ -8149,7 +8149,7 @@ sys/src/9/pc/vgatvp3026.c - 664 sys sys 1131290603 3956
 sys/src/9/pc/vgavesa.c - 664 sys sys 1131402428 2396
 sys/src/9/pc/vgavmware.c - 664 sys sys 1131290604 5840
 sys/src/9/pc/vgax.c - 664 sys sys 1131290604 1671
-sys/src/9/pc/wavelan.c - 664 sys sys 1146151713 27760
+sys/src/9/pc/wavelan.c - 664 sys sys 1185652512 27841
 sys/src/9/pc/wavelan.h - 664 sys sys 1107448246 6169
 sys/src/9/port - 20000000775 sys sys 1161222882 0
 sys/src/9/port/alarm.c - 664 sys sys 1134042902 1425

+ 4 - 4
dist/replica/plan9.db

@@ -8044,8 +8044,8 @@ sys/src/9/pc/ether2114x.c - 664 sys sys 1184468570 41707
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether79c970.c - 664 sys sys 1160070602 14088
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
-sys/src/9/pc/ether8139.c - 664 sys sys 1185509068 18584
-sys/src/9/pc/ether8169.c - 664 sys sys 1185509068 25466
+sys/src/9/pc/ether8139.c - 664 sys sys 1185650567 19974
+sys/src/9/pc/ether8169.c - 664 sys sys 1185650568 26932
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1131290377 32294
 sys/src/9/pc/ether82557.c - 664 sys sys 1185509068 30197
 sys/src/9/pc/ether82563.c - 664 sys sys 1178932992 32729
@@ -8055,7 +8055,7 @@ sys/src/9/pc/ether8390.h - 664 sys sys 1015014517 1511
 sys/src/9/pc/etherdp83820.c - 664 sys sys 1184468435 29621
 sys/src/9/pc/etherec2t.c - 664 sys sys 1135784135 4092
 sys/src/9/pc/etherelnk3.c - 664 sys sys 1158012427 48807
-sys/src/9/pc/etherga620.c - 664 sys sys 1175322931 29912
+sys/src/9/pc/etherga620.c - 664 sys sys 1185652495 29895
 sys/src/9/pc/etherga620fw.h - 664 sys sys 1026847642 222295
 sys/src/9/pc/etherif.h - 664 sys sys 1088178711 961
 sys/src/9/pc/etherigbe.c - 664 sys sys 1184468343 44976
@@ -8149,7 +8149,7 @@ sys/src/9/pc/vgatvp3026.c - 664 sys sys 1131290603 3956
 sys/src/9/pc/vgavesa.c - 664 sys sys 1131402428 2396
 sys/src/9/pc/vgavmware.c - 664 sys sys 1131290604 5840
 sys/src/9/pc/vgax.c - 664 sys sys 1131290604 1671
-sys/src/9/pc/wavelan.c - 664 sys sys 1146151713 27760
+sys/src/9/pc/wavelan.c - 664 sys sys 1185652512 27841
 sys/src/9/pc/wavelan.h - 664 sys sys 1107448246 6169
 sys/src/9/port - 20000000775 sys sys 1161222882 0
 sys/src/9/port/alarm.c - 664 sys sys 1134042902 1425

+ 4 - 0
dist/replica/plan9.log

@@ -49696,3 +49696,7 @@
 1185566405 0 c sys/man/3/ip - 664 sys sys 1185565401 26009
 1185566405 1 c sys/src/cmd/ip/6in4.c - 664 sys sys 1185564832 7472
 1185568204 0 c 386/bin/upas/smtp - 775 sys sys 1185566684 275107
+1185651005 0 c sys/src/9/pc/ether8139.c - 664 sys sys 1185650567 19974
+1185651005 1 c sys/src/9/pc/ether8169.c - 664 sys sys 1185650568 26932
+1185652808 0 c sys/src/9/pc/etherga620.c - 664 sys sys 1185652495 29895
+1185652808 1 c sys/src/9/pc/wavelan.c - 664 sys sys 1185652512 27841

+ 1 - 1
sys/man/4/factotum

@@ -597,7 +597,7 @@ attribute with value
 .B client
 or
 .BR server ,
-and enough other attibutes to uniquely identify a key to use.
+and enough other attributes to uniquely identify a key to use.
 A
 .B start
 RPC is required before any others.    The possible replies are:

+ 71 - 3
sys/src/9/pc/ether8139.c

@@ -187,6 +187,10 @@ typedef struct Ctlr {
 	Lock	ilock;			/* init */
 	void*	alloc;			/* base of per-Ctlr allocated data */
 
+	int	pcie;			/* flag: pci-express device? */
+
+	uvlong	mchash;			/* multicast hash */
+
 	int	rcr;			/* receive configuration register */
 	uchar*	rbstart;		/* receive buffer */
 	int	rblen;			/* receive buffer length */
@@ -204,6 +208,7 @@ typedef struct Ctlr {
 	int	dis;			/* disconnect counter */
 	int	fcsc;			/* false carrier sense counter */
 	int	rec;			/* RX_ER counter */
+	uint	mcast;
 } Ctlr;
 
 static Ctlr* ctlrhead;
@@ -234,10 +239,67 @@ rtl8139promiscuous(void* arg, int on)
 	iunlock(&ctlr->ilock);
 }
 
+enum {
+	/* everyone else uses 0x04c11db7, but they both produce the same crc */
+	Etherpolybe = 0x04c11db6,
+	Bytemask = (1<<8) - 1,
+};
+
+static ulong
+ethercrcbe(uchar *addr, long len)
+{
+	int i, j;
+	ulong c, crc, carry;
+
+	crc = ~0UL;
+	for (i = 0; i < len; i++) {
+		c = addr[i];
+		for (j = 0; j < 8; j++) {
+			carry = ((crc & (1UL << 31))? 1: 0) ^ (c & 1);
+			crc <<= 1;
+			c >>= 1;
+			if (carry)
+				crc = (crc ^ Etherpolybe) | carry;
+		}
+	}
+	return crc;
+}
+
+static ulong
+swabl(ulong l)
+{
+	return l>>24 | (l>>8) & (Bytemask<<8) |
+		(l<<8) & (Bytemask<<16) | l<<24;
+}
+
 static void
-rtl8139multicast(void* arg, uchar*, int)
+rtl8139multicast(void* ether, uchar *eaddr, int add)
 {
-	rtl8139promiscuous(arg, 1);
+	Ether *edev;
+	Ctlr *ctlr;
+
+	if (!add)
+		return;	/* ok to keep receiving on old mcast addrs */
+
+	edev = ether;
+	ctlr = edev->ctlr;
+	ilock(&ctlr->ilock);
+
+	ctlr->mchash |= 1ULL << (ethercrcbe(eaddr, Eaddrlen) >> 26);
+
+	ctlr->rcr |= Am;
+	csr32w(ctlr, Rcr, ctlr->rcr);
+
+	/* pci-e variants reverse the order of the hash byte registers */
+	if (0 && ctlr->pcie) {
+		csr32w(ctlr, Mar0,   swabl(ctlr->mchash>>32));
+		csr32w(ctlr, Mar0+4, swabl(ctlr->mchash));
+	} else {
+		csr32w(ctlr, Mar0,   ctlr->mchash);
+		csr32w(ctlr, Mar0+4, ctlr->mchash>>32);
+	}
+
+	iunlock(&ctlr->ilock);
 }
 
 static long
@@ -250,6 +312,7 @@ rtl8139ifstat(Ether* edev, void* a, long n, ulong offset)
 	ctlr = edev->ctlr;
 	p = malloc(READSTR);
 	l = snprint(p, READSTR, "rcr %#8.8ux\n", ctlr->rcr);
+	l += snprint(p+l, READSTR-l, "multicast %ud\n", ctlr->mcast);
 	l += snprint(p+l, READSTR-l, "ierrs %d\n", ctlr->ierrs);
 	l += snprint(p+l, READSTR-l, "etxth %d\n", ctlr->etxth);
 	l += snprint(p+l, READSTR-l, "taligned %d\n", ctlr->taligned);
@@ -345,7 +408,7 @@ rtl8139init(Ether* edev)
 	alloc += ctlr->rblen+16;
 	memset(ctlr->rbstart, 0, ctlr->rblen+16);
 	csr32w(ctlr, Rbstart, PCIWADDR(ctlr->rbstart));
-	ctlr->rcr = Rxfth256|Rblen|Mrxdmaunlimited|Ab|Apm;
+	ctlr->rcr = Rxfth256|Rblen|Mrxdmaunlimited|Ab|Am|Apm;
 
 	/*
 	 * Transmitter.
@@ -374,6 +437,9 @@ rtl8139init(Ether* edev)
 	csr8w(ctlr, Cr, Te|Re);
 	csr32w(ctlr, Tcr, Mtxdma2048);
 	csr32w(ctlr, Rcr, ctlr->rcr);
+	csr32w(ctlr, Mar0,   0);
+	csr32w(ctlr, Mar0+4, 0);
+	ctlr->mchash = 0;
 
 	iunlock(&ctlr->ilock);
 }
@@ -498,6 +564,8 @@ rtl8139receive(Ether* edev)
 		capr = (capr+4) % ctlr->rblen;
 		p = ctlr->rbstart+capr;
 		capr = (capr+length) % ctlr->rblen;
+		if(status & Mar)
+			ctlr->mcast++;
 
 		if((bp = iallocb(length)) != nil){
 			if(p+length >= ctlr->rbstart+ctlr->rblen){

+ 78 - 7
sys/src/9/pc/ether8169.c

@@ -236,10 +236,10 @@ struct Dtcc {
 };
 
 enum {						/* Variants */
-	Rtl8100e	= (0x8136<<16)|0x10EC,	/* RTL810[01]E ? */
+	Rtl8100e	= (0x8136<<16)|0x10EC,	/* RTL810[01]E: pci -e */
 	Rtl8169c	= (0x0116<<16)|0x16EC,	/* RTL8169C+ (USR997902) */
 	Rtl8169sc	= (0x8167<<16)|0x10EC,	/* RTL8169SC */
-	Rtl8168b	= (0x8168<<16)|0x10EC,	/* RTL8168B */
+	Rtl8168b	= (0x8168<<16)|0x10EC,	/* RTL8168B: pci-e */
 	Rtl8169		= (0x8169<<16)|0x10EC,	/* RTL8169 */
 };
 
@@ -257,6 +257,9 @@ typedef struct Ctlr {
 	int	pciv;			/*  */
 	int	macv;			/* MAC version */
 	int	phyv;			/* PHY version */
+	int	pcie;			/* flag: pci-express device? */
+
+	uvlong	mchash;			/* multicast hash */
 
 	Mii*	mii;
 
@@ -297,6 +300,7 @@ typedef struct Ctlr {
 	uint	rdu;
 	uint	punlc;
 	uint	fovw;
+	uint	mcast;
 } Ctlr;
 
 static Ctlr* rtl8169ctlrhead;
@@ -414,10 +418,67 @@ rtl8169promiscuous(void* arg, int on)
 	iunlock(&ctlr->ilock);
 }
 
+enum {
+	/* everyone else uses 0x04c11db7, but they both produce the same crc */
+	Etherpolybe = 0x04c11db6,
+	Bytemask = (1<<8) - 1,
+};
+
+static ulong
+ethercrcbe(uchar *addr, long len)
+{
+	int i, j;
+	ulong c, crc, carry;
+
+	crc = ~0UL;
+	for (i = 0; i < len; i++) {
+		c = addr[i];
+		for (j = 0; j < 8; j++) {
+			carry = ((crc & (1UL << 31))? 1: 0) ^ (c & 1);
+			crc <<= 1;
+			c >>= 1;
+			if (carry)
+				crc = (crc ^ Etherpolybe) | carry;
+		}
+	}
+	return crc;
+}
+
+static ulong
+swabl(ulong l)
+{
+	return l>>24 | (l>>8) & (Bytemask<<8) |
+		(l<<8) & (Bytemask<<16) | l<<24;
+}
+
 static void
-rtl8169multicast(void* arg, uchar*, int)
+rtl8169multicast(void* ether, uchar *eaddr, int add)
 {
-	rtl8169promiscuous(arg, 1);
+	Ether *edev;
+	Ctlr *ctlr;
+
+	if (!add)
+		return;	/* ok to keep receiving on old mcast addrs */
+
+	edev = ether;
+	ctlr = edev->ctlr;
+	ilock(&ctlr->ilock);
+
+	ctlr->mchash |= 1ULL << (ethercrcbe(eaddr, Eaddrlen) >> 26);
+
+	ctlr->rcr |= Am;
+	csr32w(ctlr, Rcr, ctlr->rcr);
+
+	/* pci-e variants reverse the order of the hash byte registers */
+	if (ctlr->pcie) {
+		csr32w(ctlr, Mar0,   swabl(ctlr->mchash>>32));
+		csr32w(ctlr, Mar0+4, swabl(ctlr->mchash));
+	} else {
+		csr32w(ctlr, Mar0,   ctlr->mchash);
+		csr32w(ctlr, Mar0+4, ctlr->mchash>>32);
+	}
+
+	iunlock(&ctlr->ilock);
 }
 
 static long
@@ -491,6 +552,7 @@ rtl8169ifstat(Ether* edev, void* a, long n, ulong offset)
 
 	l += snprint(p+l, READSTR-l, "tcr: %#8.8ux\n", ctlr->tcr);
 	l += snprint(p+l, READSTR-l, "rcr: %#8.8ux\n", ctlr->rcr);
+	l += snprint(p+l, READSTR-l, "multicast: %ud\n", ctlr->mcast);
 
 	if(ctlr->mii != nil && ctlr->mii->curphy != nil){
 		l += snprint(p+l, READSTR, "phy:   ");
@@ -621,7 +683,7 @@ rtl8169init(Ether* edev)
 		}
 	}
 	rtl8169replenish(ctlr);
-	ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Apm;
+	ctlr->rcr = Rxfthnone|Mrxdmaunlimited|Ab|Am|Apm;
 
 	/*
 	 * Mtps is in units of 128 except for the RTL8169
@@ -683,6 +745,9 @@ rtl8169init(Ether* edev)
 		csr8w(ctlr, Cr, Te|Re);
 		csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited);
 		csr32w(ctlr, Rcr, ctlr->rcr);
+		csr32w(ctlr, Mar0,   0);
+		csr32w(ctlr, Mar0+4, 0);
+		ctlr->mchash = 0;
 	case Rtl8169sc:
 	case Rtl8168b:
 		break;
@@ -902,6 +967,8 @@ rtl8169receive(Ether* edev)
 
 			if(control & Fovf)
 				ctlr->fovf++;
+			if(control & Mar)
+				ctlr->mcast++;
 
 			switch(control & (Pid1|Pid0)){
 			default:
@@ -999,20 +1066,23 @@ rtl8169pci(void)
 {
 	Pcidev *p;
 	Ctlr *ctlr;
-	int i, port;
+	int i, port, pcie;
 
 	p = nil;
 	while(p = pcimatch(p, 0, 0)){
 		if(p->ccrb != 0x02 || p->ccru != 0)
 			continue;
 
+		pcie = 0;
 		switch(i = ((p->did<<16)|p->vid)){
 		default:
 			continue;
 		case Rtl8100e:			/* RTL810[01]E ? */
+		case Rtl8168b:			/* RTL8168B */
+			pcie = 1;
+			break;
 		case Rtl8169c:			/* RTL8169C */
 		case Rtl8169sc:			/* RTL8169SC */
-		case Rtl8168b:			/* RTL8168B */
 		case Rtl8169:			/* RTL8169 */
 			break;
 		case (0xC107<<16)|0x1259:	/* Corega CG-LAPCIGT */
@@ -1030,6 +1100,7 @@ rtl8169pci(void)
 		ctlr->port = port;
 		ctlr->pcidev = p;
 		ctlr->pciv = i;
+		ctlr->pcie = pcie;
 
 		if(pcigetpms(p) > 0){
 			pcisetpms(p, 0);

+ 3 - 3
sys/src/9/pc/etherga620.c

@@ -1201,13 +1201,13 @@ ga620promiscuous(void *arg, int on)
 }
 
 static void
-ga620multicast(void *arg, uchar *addr, int on)
+ga620multicast(void *arg, uchar *addr, int add)
 {
 	Ether *ether = arg;
 
 	USED(addr);
-	/* 3rd arg: 1 enables, 2 disables */
-	ga620command(ether->ctlr, 0xe, (on? 1: 2), 0);
+	if (add)
+		ga620command(ether->ctlr, 0xe, 1, 0);	/* 1 == enable */
 }
 
 static int

+ 5 - 3
sys/src/9/pc/wavelan.c

@@ -12,9 +12,9 @@
 	long. When it gets robust, locks should be revisited.
 
 	BUGS: check endian, alignment and mem/io issues;
-	      multicast;
 	      receive watchdog interrupts.
 	TODO: automatic power management;
+	      multicast filtering;
 	      improve locking.
  */
 #include "u.h"
@@ -736,9 +736,11 @@ w_timer(void* arg)
 }
 
 void
-w_multicast(void*, uchar*, int)
+w_multicast(void *ether, uchar*, int add)
 {
-	// BUG: to be added.
+	/* BUG: use controller's multicast filter */
+	if (add)
+		w_promiscuous(ether, 1);
 }
 
 void