Browse Source

Plan 9 from Bell Labs 2008-06-10

David du Colombier 12 years ago
parent
commit
f552de72b6
5 changed files with 214 additions and 76 deletions
  1. 3 3
      dist/replica/_plan9.db
  2. 3 3
      dist/replica/plan9.db
  3. 3 0
      dist/replica/plan9.log
  4. 87 64
      sys/src/9/pc/ether82563.c
  5. 118 6
      sys/src/boot/pc/ether82563.c

+ 3 - 3
dist/replica/_plan9.db

@@ -500,7 +500,7 @@
 386/bin/vac - 775 sys sys 1196742539 171330
 386/bin/vacfs - 775 sys sys 1196742542 176138
 386/bin/venti - 20000000775 sys sys 947360466 0
-386/bin/venti/buildindex - 775 sys sys 1212695266 259494
+386/bin/venti/buildindex - 775 sys sys 1212982782 259535
 386/bin/venti/checkarenas - 775 sys sys 1211255666 261314
 386/bin/venti/checkindex - 775 sys sys 1211255671 256744
 386/bin/venti/clumpstats - 775 sys sys 1211255677 245680
@@ -8124,7 +8124,7 @@ sys/src/9/pc/ether8139.c - 664 sys sys 1185650567 19974
 sys/src/9/pc/ether8169.c - 664 sys sys 1185812348 26931
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1131290377 32294
 sys/src/9/pc/ether82557.c - 664 sys sys 1211922643 30457
-sys/src/9/pc/ether82563.c - 664 sys sys 1200342471 37076
+sys/src/9/pc/ether82563.c - 664 sys sys 1213016020 37776
 sys/src/9/pc/ether82598.c - 664 sys sys 1203982856 18364
 sys/src/9/pc/ether83815.c - 664 sys sys 1172259521 26346
 sys/src/9/pc/ether8390.c - 664 sys sys 1131290377 17702
@@ -9206,7 +9206,7 @@ sys/src/boot/pc/ether8003.c - 664 sys sys 1015007950 6446
 sys/src/boot/pc/ether8139.c - 664 sys sys 1121393459 14823
 sys/src/boot/pc/ether8169.c - 664 sys sys 1212010436 21868
 sys/src/boot/pc/ether82557.c - 664 sys sys 1212010428 19134
-sys/src/boot/pc/ether82563.c - 664 sys sys 1209184829 26037
+sys/src/boot/pc/ether82563.c - 664 sys sys 1213016004 28290
 sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
 sys/src/boot/pc/ether8390.c - 664 sys sys 1212010420 16207
 sys/src/boot/pc/ether8390.h - 664 sys sys 1015007951 1392

+ 3 - 3
dist/replica/plan9.db

@@ -500,7 +500,7 @@
 386/bin/vac - 775 sys sys 1196742539 171330
 386/bin/vacfs - 775 sys sys 1196742542 176138
 386/bin/venti - 20000000775 sys sys 947360466 0
-386/bin/venti/buildindex - 775 sys sys 1212695266 259494
+386/bin/venti/buildindex - 775 sys sys 1212982782 259535
 386/bin/venti/checkarenas - 775 sys sys 1211255666 261314
 386/bin/venti/checkindex - 775 sys sys 1211255671 256744
 386/bin/venti/clumpstats - 775 sys sys 1211255677 245680
@@ -8124,7 +8124,7 @@ sys/src/9/pc/ether8139.c - 664 sys sys 1185650567 19974
 sys/src/9/pc/ether8169.c - 664 sys sys 1185812348 26931
 sys/src/9/pc/ether82543gc.c - 664 sys sys 1131290377 32294
 sys/src/9/pc/ether82557.c - 664 sys sys 1211922643 30457
-sys/src/9/pc/ether82563.c - 664 sys sys 1200342471 37076
+sys/src/9/pc/ether82563.c - 664 sys sys 1213016020 37776
 sys/src/9/pc/ether82598.c - 664 sys sys 1203982856 18364
 sys/src/9/pc/ether83815.c - 664 sys sys 1172259521 26346
 sys/src/9/pc/ether8390.c - 664 sys sys 1131290377 17702
@@ -9206,7 +9206,7 @@ sys/src/boot/pc/ether8003.c - 664 sys sys 1015007950 6446
 sys/src/boot/pc/ether8139.c - 664 sys sys 1121393459 14823
 sys/src/boot/pc/ether8169.c - 664 sys sys 1212010436 21868
 sys/src/boot/pc/ether82557.c - 664 sys sys 1212010428 19134
-sys/src/boot/pc/ether82563.c - 664 sys sys 1209184829 26037
+sys/src/boot/pc/ether82563.c - 664 sys sys 1213016004 28290
 sys/src/boot/pc/ether83815.c - 664 sys sys 1144961190 21993
 sys/src/boot/pc/ether8390.c - 664 sys sys 1212010420 16207
 sys/src/boot/pc/ether8390.h - 664 sys sys 1015007951 1392

+ 3 - 0
dist/replica/plan9.log

@@ -19833,3 +19833,6 @@
 1212696005 0 c 386/bin/venti/buildindex - 775 sys sys 1212695266 259494
 1212724805 0 c 386/bin/upas/nedmail - 775 sys sys 1212724063 156265
 1212975003 0 c sys/src/cmd/venti/srv/buildindex.c - 664 sys sys 1212974464 21739
+1212984005 0 c 386/bin/venti/buildindex - 775 sys sys 1212982782 259535
+1213016405 0 c sys/src/9/pc/ether82563.c - 664 sys sys 1213016020 37776
+1213016405 1 c sys/src/boot/pc/ether82563.c - 664 sys sys 1213016004 28290

+ 87 - 64
sys/src/9/pc/ether82563.c

@@ -184,12 +184,29 @@ enum {					/* Mdic */
 	MDIe		= 0x40000000,	/* Error */
 };
 
-enum {					/* Mdic secondary status register */
-	Physsr		= 17,		/* phy secondary status register */
-	Phyier		= 18,		/* phy interrupt enable register */
-	Phypage		= 22,		/* phy page register */
+enum {					/* phy interface registers */
+	Phyctl		= 0,		/* phy ctl */
+	Physsr		= 17,		/* phy secondary status */
+	Phyier		= 18,		/* 82573 phy interrupt enable */
+	Phyisr		= 19,		/* 82563 phy interrupt status */
+	Phylhr		= 19,		/* 8257[12] link health */
+
 	Rtlink		= 1<<10,	/* realtime link status */
-	Phyan		= 1<<11,	/* phy has autonegotiated */
+	Phyan		= 1<<11,	/* phy has auto-negotiated */
+
+	/* Phyctl bits */
+	Ran		= 1<<9,		/* restart auto-negotiation */
+	Ean		= 1<<12,	/* enable auto-negotiation */
+
+	/* 82573 Phyier bits */
+	Lscie		= 1<<10,	/* link status changed ie */
+	Ancie		= 1<<11,	/* auto-negotiation complete ie */
+	Spdie		= 1<<14,	/* speed changed ie */
+	Panie		= 1<<15,	/* phy auto-negotiation error ie */
+
+	/* Phylhr/Phyisr bits */
+	Anf		= 1<<6,		/* lhr: auto-negotiation fault */
+	Ane		= 1<<15,	/* isr: auto-negotiation error */
 };
 
 enum {					/* Icr, Ics, Ims, Imc */
@@ -657,7 +674,7 @@ static Cmdtab i82563ctlmsg[] = {
 static long
 i82563ctl(Ether* edev, void* buf, long n)
 {
-	int v;
+	ulong v;
 	char *p;
 	Ctlr *ctlr;
 	Cmdbuf *cb;
@@ -675,15 +692,15 @@ i82563ctl(Ether* edev, void* buf, long n)
 	ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
 	switch(ct->index){
 	case CMrdtr:
-		v = strtol(cb->f[1], &p, 0);
-		if(v < 0 || p == cb->f[1] || v > 0xFFFF)
+		v = strtoul(cb->f[1], &p, 0);
+		if(p == cb->f[1] || v > 0xFFFF)
 			error(Ebadarg);
 		ctlr->rdtr = v;
 		csr32w(ctlr, Rdtr, v);
 		break;
 	case CMradv:
-		v = strtol(cb->f[1], &p, 0);
-		if(v < 0 || p == cb->f[1] || v > 0xFFFF)
+		v = strtoul(cb->f[1], &p, 0);
+		if(p == cb->f[1] || v > 0xFFFF)
 			error(Ebadarg);
 		ctlr->radv = v;
 		csr32w(ctlr, Radv, v);
@@ -751,6 +768,7 @@ i82563rballoc(void)
 	if((bp = i82563rbpool) != nil){
 		i82563rbpool = bp->next;
 		bp->next = nil;
+		_xinc(&bp->ref);
 	}
 	iunlock(&i82563rblock);
 
@@ -1003,36 +1021,36 @@ i82563rproc(void* arg)
 			 * an indication of whether the checksums were
 			 * calculated and valid.
 			 */
-			if (bp = ctlr->rb[rdh]) {
-				if((rd->status & Reop) && rd->errors == 0){
-					bp->wp += rd->length;
-					bp->lim = bp->wp;	/* lie like a dog. */
-					if(!(rd->status & Ixsm)){
-						ctlr->ixsm++;
-						if(rd->status & Ipcs){
-							/*
-							 * IP checksum calculated
-							 * (and valid as errors == 0).
-							 */
-							ctlr->ipcs++;
-							bp->flag |= Bipck;
-						}
-						if(rd->status & Tcpcs){
-							/*
-							 * TCP/UDP checksum calculated
-							 * (and valid as errors == 0).
-							 */
-							ctlr->tcpcs++;
-							bp->flag |= Btcpck|Budpck;
-						}
-						bp->checksum = rd->checksum;
-						bp->flag |= Bpktck;
+			bp = ctlr->rb[rdh];
+			if((rd->status & Reop) && rd->errors == 0){
+				bp->wp += rd->length;
+				bp->lim = bp->wp;	/* lie like a dog. */
+				if(!(rd->status & Ixsm)){
+					ctlr->ixsm++;
+					if(rd->status & Ipcs){
+						/*
+						 * IP checksum calculated
+						 * (and valid as errors == 0).
+						 */
+						ctlr->ipcs++;
+						bp->flag |= Bipck;
+					}
+					if(rd->status & Tcpcs){
+						/*
+						 * TCP/UDP checksum calculated
+						 * (and valid as errors == 0).
+						 */
+						ctlr->tcpcs++;
+						bp->flag |= Btcpck|Budpck;
 					}
-					etheriq(edev, bp, 1);
-				} else
-					freeb(bp);
-				ctlr->rb[rdh] = nil;
-			}
+					bp->checksum = rd->checksum;
+					bp->flag |= Bpktck;
+				}
+				etheriq(edev, bp, 1);
+			} else
+				freeb(bp);
+			ctlr->rb[rdh] = nil;
+
 			rd->status = 0;
 			ctlr->rdfree--;
 			ctlr->rdh = rdh = Next(rdh, m);
@@ -1088,42 +1106,47 @@ phywrite(Ctlr *c, int reg, ushort val)
 	return 0;
 }
 
+/*
+ * watch for changes of link state
+ */
 static void
 i82563lproc(void *v)
 {
-	Ether *e;
+	uint phy, i, a;
 	Ctlr *c;
-	uint phy, i;
+	Ether *e;
 
 	e = v;
 	c = e->ctlr;
 
-	phy = phyread(c, Phyier);
-	if(phy != ~0){
-		phy |= 1<<14;
-		phywrite(c, Phyier, phy);
-	}
-
+	if(c->type == i82573 && (phy = phyread(c, Phyier)) != ~0)
+		phywrite(c, Phyier, phy | Lscie | Ancie | Spdie | Panie);
 	for(;;){
 		phy = phyread(c, Physsr);
 		if(phy == ~0)
 			goto next;
-		e->link = (phy & Rtlink) != 0;
 		i = (phy>>14) & 3;
 
 		switch(c->type){
 		case i82563:
-			if((phy&Phyan) == 0)
-				goto next;
+			a = phyread(c, Phyisr) & Ane;
 			break;
 		case i82571:
 		case i82572:
+			a = phyread(c, Phylhr) & Anf;
 			i = (i-1) & 3;
 			break;
+		default:
+			a = 0;
+			break;
+		}
+		if(a)
+			phywrite(c, Phyctl, phyread(c, Phyctl) | Ran | Ean);
+		e->link = (phy & Rtlink) != 0;
+		if(e->link){
+			c->speeds[i]++;
+			e->mbps = speedtab[i];
 		}
-
-		c->speeds[i]++;
-		e->mbps = speedtab[i];
 next:
 		c->lim = 0;
 		i82563im(c, Lsc);
@@ -1167,7 +1190,7 @@ i82563attach(Ether* edev)
 		qunlock(&ctlr->alock);
 		return;
 	}
-	ctlr->rdba = (Rd*)ROUNDUP((ulong)ctlr->alloc, 256);
+	ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
 	ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
 
 	ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
@@ -1405,11 +1428,10 @@ fload(Ctlr *c)
 		return -1;
 	f.reg32 = (ulong*)f.reg;
 	f.sz = f.reg32[Bfpr];
-	if(csr32r(c, Eec) & (1<<22)){
-		r = (f.sz >> 16) & 0x1fff;
-		r = (r+1) << 12;
-	}else
-		r = (f.sz & 0x1fff) << 12;
+	r = f.sz & 0x1fff;
+	if(csr32r(c, Eec) & (1<<22))
+		++r;
+	r <<= 12;
 
 	sum = 0;
 	for (adr = 0; adr < 0x40; adr++) {
@@ -1440,9 +1462,9 @@ i82563reset(Ctlr *ctlr)
 		return -1;
 	}
 
-	for(i = Ea; i < Eaddrlen/2; i++){
-		ctlr->ra[2*i]   = ctlr->eeprom[i];
-		ctlr->ra[2*i+1] = ctlr->eeprom[i] >> 8;
+	for(i = 0; i < Eaddrlen/2; i++){
+		ctlr->ra[2*i]   = ctlr->eeprom[Ea+i];
+		ctlr->ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
 	}
 	r = (csr32r(ctlr, Status) & Lanid) >> 2;
 	ctlr->ra[5] += r;		/* ea ctlr[1] = ea ctlr[0]+1 */
@@ -1489,6 +1511,7 @@ i82563pci(void)
 		case 0x1049:		/* mm */
 		case 0x104a:		/* dm */
 		case 0x104d:		/* v */
+		case 0x10bd:		/* dm */
 			type = i82566;
 			break;
 		case 0x10a4:
@@ -1508,8 +1531,7 @@ i82563pci(void)
 		io = p->mem[0].bar & ~0x0F;
 		mem = vmap(io, p->mem[0].size);
 		if(mem == nil){
-			print("%s: can't map %.8lux\n", tname[type],
-				p->mem[0].bar);
+			print("%s: can't map %.8lux\n", tname[type], io);
 			continue;
 		}
 		ctlr = malloc(sizeof(Ctlr));
@@ -1520,6 +1542,7 @@ i82563pci(void)
 		ctlr->nic = mem;
 
 		if(i82563reset(ctlr)){
+			vunmap(mem, p->mem[0].size);
 			free(ctlr);
 			continue;
 		}

+ 118 - 6
sys/src/boot/pc/ether82563.c

@@ -378,6 +378,33 @@ enum {					/* Tdesc status */
 	CssSHIFT	= 8,
 };
 
+typedef struct {
+	ushort	*reg;
+	ulong	*reg32;
+	int	sz;
+} Flash;
+
+enum {
+	/* 16 and 32-bit flash registers for ich flash parts */
+	Bfpr	= 0x00/4,		/* flash base 0:12; lim 16:28 */
+	Fsts	= 0x04/2,		/* flash status;  Hsfsts */
+	Fctl	= 0x06/2,		/* flash control; Hsfctl */
+	Faddr	= 0x08/4,		/* flash address to r/w */
+	Fdata	= 0x10/4,		/* data @ address */
+
+	/* status register */
+	Fdone	= 1<<0,			/* flash cycle done */
+	Fcerr	= 1<<1,			/* cycle error; write 1 to clear */
+	Ael	= 1<<2,			/* direct access error log; 1 to clear */
+	Scip	= 1<<5,			/* spi cycle in progress */
+	Fvalid	= 1<<14,		/* flash descriptor valid */
+
+	/* control register */
+	Fgo	= 1<<0,			/* start cycle */
+	Flcycle	= 1<<1,			/* two bits: r=0; w=2 */
+	Fdbc	= 1<<8,			/* bytes to read; 5 bits */
+};
+
 enum {
 	Nrdesc		= 128,		/* multiple of 8 */
 	Ntdesc		= 128,		/* multiple of 8 */
@@ -800,6 +827,89 @@ i82563shutdown(Ether* ether)
 	i82563detach(ether);
 }
 
+static int
+fcycle(Ctlr *, Flash *f)
+{
+	ushort s, i;
+
+	s = f->reg[Fsts];
+	if((s&Fvalid) == 0)
+		return -1;
+	f->reg[Fsts] |= Fcerr | Ael;
+	for(i = 0; i < 10; i++){
+		if((s&Scip) == 0)
+			return 0;
+		delay(1);
+		s = f->reg[Fsts];
+	}
+	return -1;
+}
+
+static int
+fread(Ctlr *c, Flash *f, int ladr)
+{
+	ushort s;
+
+	delay(1);
+	if(fcycle(c, f) == -1)
+		return -1;
+	f->reg[Fsts] |= Fdone;
+	f->reg32[Faddr] = ladr;
+
+	/* setup flash control register */
+	s = f->reg[Fctl];
+	s &= ~(0x1f << 8);
+	s |= (2-1) << 8;		/* 2 bytes */
+	s &= ~(2*Flcycle);		/* read */
+	f->reg[Fctl] = s | Fgo;
+
+	while((f->reg[Fsts] & Fdone) == 0)
+		;
+	if(f->reg[Fsts] & (Fcerr|Ael))
+		return -1;
+	return f->reg32[Fdata] & 0xffff;
+}
+
+static int
+fload(Ctlr *c)
+{
+	ulong data, io, r, adr;
+	ushort sum;
+	Flash f;
+	Pcidev *p;
+
+//	io = c->pcidev->mem[1].bar & ~0x0f;
+//	f.reg = vmap(io, c->pcidev->mem[1].size);
+//	if(f.reg == nil)
+//		return -1;
+
+	p = c->pcidev;
+	io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
+	if(io == 0){
+		print("i82566: can't map flash @ 0x%8.8lux\n", p->mem[1].bar);
+		return -1;
+	}
+	f.reg = KADDR(io);
+
+	f.reg32 = (ulong*)f.reg;
+	f.sz = f.reg32[Bfpr];
+	r = f.sz & 0x1fff;
+	if(csr32r(c, Eec) & (1<<22))
+		++r;
+	r <<= 12;
+
+	sum = 0;
+	for (adr = 0; adr < 0x40; adr++) {
+		data = fread(c, &f, r + adr*2);
+		if(data == -1)
+			break;
+		c->eeprom[adr] = data;
+		sum += data;
+	}
+//	vunmap(f.reg, c->pcidev->mem[1].size);
+	return sum;
+}
+
 static int
 i82563reset(Ctlr* ctlr)
 {
@@ -807,11 +917,9 @@ i82563reset(Ctlr* ctlr)
 
 	detach(ctlr);
 
-	if(ctlr->type == i82566) {
-		// r = fload(ctlr);
-		r = 0;
-		print("i82566 not done yet\n");
-	} else
+	if(ctlr->type == i82566)
+		r = fload(ctlr);
+	else
 		r = eeload(ctlr);
 	if (r != 0 && r != 0xBABA){
 		print("%s: bad EEPROM checksum - 0x%4.4ux\n", Type, r);
@@ -869,6 +977,9 @@ i82563pci(void)
 
 	p = nil;
 	while(p = pcimatch(p, 0x8086, 0)){
+		if(p->ccrb != 0x02 || p->ccru != 0)
+			continue;
+print("i82563pci: did %4.4#x\n", p->did);
 		switch(p->did){
 		case 0x1096:
 		case 0x10ba:
@@ -877,6 +988,7 @@ i82563pci(void)
 		case 0x1049:		/* mm */
 		case 0x104a:		/* dm */
 		case 0x104d:		/* v */
+		case 0x10bd:		/* dm */
 			type = i82566;
 			break;
 		case 0x10a4:
@@ -995,11 +1107,11 @@ i82563pnp(Ether* edev)
 	 * ideally, we recognize the interface, note it's down and move on.
 	 * currently either we can skip the interface or note it is down,
 	 * but not both.
-	 */
 	if((csr32r(ctlr, Status)&Lu) == 0){
 		print("ether#%d: 82563 (%s): link down\n", edev->ctlrno, Type);
 		return -1;
 	}
+	 */
 
 	return 0;
 }