Browse Source

Plan 9 from Bell Labs 2008-10-12

David du Colombier 15 years ago
parent
commit
a16fa9701e
6 changed files with 132 additions and 67 deletions
  1. 3 3
      dist/replica/_plan9.db
  2. 3 3
      dist/replica/plan9.db
  3. 3 0
      dist/replica/plan9.log
  4. 119 57
      sys/src/9/pc/ether82563.c
  5. 2 2
      sys/src/9/port/netif.c
  6. 2 2
      sys/src/9/port/netif.h

+ 3 - 3
dist/replica/_plan9.db

@@ -8128,7 +8128,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 1213016020 37776
+sys/src/9/pc/ether82563.c - 664 sys sys 1223767244 39197
 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
@@ -8295,8 +8295,8 @@ sys/src/9/port/mkrootall - 775 sys sys 1191430540 453
 sys/src/9/port/mkrootc - 775 sys sys 1055954695 717
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
-sys/src/9/port/netif.c - 664 sys sys 1178831077 13474
-sys/src/9/port/netif.h - 664 sys sys 1187735815 3059
+sys/src/9/port/netif.c - 664 sys sys 1223761957 13480
+sys/src/9/port/netif.h - 664 sys sys 1223761957 3065
 sys/src/9/port/page.c - 664 sys sys 1218341935 11124
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/pgrp.c - 664 sys sys 1210369414 5000

+ 3 - 3
dist/replica/plan9.db

@@ -8128,7 +8128,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 1213016020 37776
+sys/src/9/pc/ether82563.c - 664 sys sys 1223767244 39197
 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
@@ -8295,8 +8295,8 @@ sys/src/9/port/mkrootall - 775 sys sys 1191430540 453
 sys/src/9/port/mkrootc - 775 sys sys 1055954695 717
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
-sys/src/9/port/netif.c - 664 sys sys 1178831077 13474
-sys/src/9/port/netif.h - 664 sys sys 1187735815 3059
+sys/src/9/port/netif.c - 664 sys sys 1223761957 13480
+sys/src/9/port/netif.h - 664 sys sys 1223761957 3065
 sys/src/9/port/page.c - 664 sys sys 1218341935 11124
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/pgrp.c - 664 sys sys 1210369414 5000

+ 3 - 0
dist/replica/plan9.log

@@ -36164,3 +36164,6 @@
 1223562605 0 c sys/man/8/gpsfs - 664 sys sys 1223562059 5097
 1223571604 0 c sys/src/cmd/vac/vacfs.c - 664 sys sys 1223571409 13386
 1223580605 0 c 386/bin/vacfs - 775 sys sys 1223579346 243644
+1223762404 0 c sys/src/9/port/netif.c - 664 sys sys 1223761957 13480
+1223762404 1 c sys/src/9/port/netif.h - 664 sys sys 1223761957 3065
+1223767805 0 c sys/src/9/pc/ether82563.c - 664 sys sys 1223767244 39197

+ 119 - 57
sys/src/9/pc/ether82563.c

@@ -1,5 +1,12 @@
 /*
- * Intel 8256[36], 8257[12], 82573[ev] Gigabit Ethernet PCI-Express Controllers
+ * Intel Gigabit Ethernet PCI-Express Controllers.
+ *	8256[36], 8257[12], 82573[ev]
+ *	82575eb
+ * Pretty basic, does not use many of the chip smarts.
+ * The interrupt mitigation tuning for each chip variant
+ * is probably different. The reset/initialisation
+ * sequence needs straightened out. Doubt the PHY code
+ * for the 82575eb is right.
  */
 #include "u.h"
 #include "../port/lib.h"
@@ -31,7 +38,7 @@ enum {
 	Fcal		= 0x0028,	/* Flow Control Address Low */
 	Fcah		= 0x002C,	/* Flow Control Address High */
 	Fct		= 0x0030,	/* Flow Control Type */
-	Kumctrlsta	= 0x0034,	/* Kumeran Controll and Status Register */
+	Kumctrlsta	= 0x0034,	/* MAC-PHY Interface */
 	Vet		= 0x0038,	/* VLAN EtherType */
 	Fcttv		= 0x0170,	/* Flow Control Transmit Timer Value */
 	Txcw		= 0x0178,	/* Transmit Configuration Word */
@@ -236,7 +243,7 @@ enum {					/* Txcw */
 	TxcwRfiMASK	= 0x00003000,	/* Remote Fault Indication */
 	TxcwRfiSHIFT	= 12,
 	TxcwNpr		= 0x00008000,	/* Next Page Request */
-	TxcwConfig	= 0x40000000,	/* Transmit COnfig Control */
+	TxcwConfig	= 0x40000000,	/* Transmit Config Control */
 	TxcwAne		= 0x80000000,	/* Auto-Negotiation Enable */
 };
 
@@ -265,7 +272,7 @@ enum {					/* Rctl */
 	Bsize1024	= 0x00010000,
 	Bsize512	= 0x00020000,
 	Bsize256	= 0x00030000,
-	BsizeFlex	= 0x08000000,	/* Flexable Bsize in 1kb increments */
+	BsizeFlex	= 0x08000000,	/* Flexible Bsize in 1KB increments */
 	Vfe		= 0x00040000,	/* VLAN Filter Enable */
 	Cfien		= 0x00080000,	/* Canonical Form Indicator Enable */
 	Cfi		= 0x00100000,	/* Canonical Form Indicator value */
@@ -298,6 +305,7 @@ enum {					/* [RT]xdctl */
 	WthreshMASK	= 0x003F0000,	/* Writeback Threshold */
 	WthreshSHIFT	= 16,
 	Gran		= 0x01000000,	/* Granularity */
+	Qenable		= 0x02000000,	/* Queue Enable (82575) */
 };
 
 enum {					/* Rxcsum */
@@ -314,12 +322,12 @@ enum {					/* Receive Delay Timer Ring */
 };
 
 typedef struct Rd {			/* Receive Descriptor */
-	uint	addr[2];
-	ushort	length;
-	ushort	checksum;
-	uchar	status;
-	uchar	errors;
-	ushort	special;
+	u32int	addr[2];
+	u16int	length;
+	u16int	checksum;
+	u8int	status;
+	u8int	errors;
+	u16int	special;
 } Rd;
 
 enum {					/* Rd status */
@@ -343,9 +351,9 @@ enum {					/* Rd errors */
 };
 
 typedef struct {			/* Transmit Descriptor */
-	uint	addr[2];		/* Data */
-	uint	control;
-	uint	status;
+	u32int	addr[2];		/* Data */
+	u32int	control;
+	u32int	status;
 } Td;
 
 enum {					/* Tdesc control */
@@ -375,8 +383,8 @@ enum {					/* Tdesc status */
 };
 
 typedef struct {
-	ushort	*reg;
-	ulong	*reg32;
+	u16int	*reg;
+	u32int	*reg32;
 	int	sz;
 } Flash;
 
@@ -414,6 +422,7 @@ enum {
 	i82571,
 	i82572,
 	i82573,
+	i82575,
 };
 
 static int rbtab[] = {
@@ -423,6 +432,7 @@ static int rbtab[] = {
 	9234,
 	9234,
 	8192,				/* terrible performance above 8k */
+	1514,
 };
 
 static char *tname[] = {
@@ -432,6 +442,7 @@ static char *tname[] = {
 	"i82571",
 	"i82572",
 	"i82573",
+	"i82575",
 };
 
 typedef struct Ctlr Ctlr;
@@ -440,12 +451,11 @@ struct Ctlr {
 	Pcidev	*pcidev;
 	Ctlr	*next;
 	int	active;
-	int	started;
 	int	type;
 	ushort	eeprom[0x40];
 
 	QLock	alock;			/* attach */
-	void	*alloc;			/* receive/transmit descriptors */
+	int	attached;
 	int	nrd;
 	int	ntd;
 	int	nrb;			/* how many this Ctlr has in the pool */
@@ -768,7 +778,7 @@ i82563rballoc(void)
 	if((bp = i82563rbpool) != nil){
 		i82563rbpool = bp->next;
 		bp->next = nil;
-		_xinc(&bp->ref);
+		_xinc(&bp->ref);	/* prevent bp from being freed */
 	}
 	iunlock(&i82563rblock);
 
@@ -818,8 +828,10 @@ i82563txinit(Ctlr* ctlr)
 	}
 	csr32w(ctlr, Tidv, 128);
 	r = csr32r(ctlr, Txdctl);
-	r &= ~WthreshMASK;
+	r &= ~(WthreshMASK|PthreshSHIFT);
 	r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
+	if(ctlr->type == i82575)
+		r |= Qenable;
 	csr32w(ctlr, Tadv, 64);
 	csr32w(ctlr, Txdctl, r);
 	r = csr32r(ctlr, Tctl);
@@ -929,20 +941,33 @@ i82563replenish(Ctlr* ctlr)
 static void
 i82563rxinit(Ctlr* ctlr)
 {
-	int i;
 	Block *bp;
+	int i, r, rctl;
 
 	if(ctlr->rbsz <= 2048)
-		csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF);
+		rctl = Dpf|Bsize2048|Bam|RdtmsHALF;
 	else if(ctlr->rbsz <= 8192)
-		csr32w(ctlr, Rctl, Lpe|Dpf|Bsize8192|Bsex|Bam|RdtmsHALF|Secrc);
+		rctl = Lpe|Dpf|Bsize8192|Bsex|Bam|RdtmsHALF|Secrc;
 	else if(ctlr->rbsz <= 12*1024){
 		i = ctlr->rbsz / 1024;
 		if(ctlr->rbsz % 1024)
 			i++;
-		csr32w(ctlr, Rctl, Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc);
-	}else
-		csr32w(ctlr, Rctl, Lpe|Dpf|Bsize16384|Bsex|Bam|RdtmsHALF|Secrc);
+		rctl = Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc;
+	}
+	else
+		rctl = Lpe|Dpf|Bsize16384|Bsex|Bam|RdtmsHALF|Secrc;
+
+	if(ctlr->type == i82575){
+		/*
+		 * Setting Qenable in Rxdctl does not
+		 * appear to stick unless Ren is on.
+		 */
+		csr32w(ctlr, Rctl, Ren|rctl);
+		r = csr32r(ctlr, Rxdctl);
+		r |= Qenable;
+		csr32w(ctlr, Rxdctl, r);
+	}
+	csr32w(ctlr, Rctl, rctl);
 
 	if(ctlr->type == i82573)
 		csr32w(ctlr, Ert, 1024/8);
@@ -962,13 +987,24 @@ i82563rxinit(Ctlr* ctlr)
 	csr32w(ctlr, Rdtr, ctlr->rdtr);
 	csr32w(ctlr, Radv, ctlr->radv);
 
-	for(i = 0; i < ctlr->nrd; i++)
+	for(i = 0; i < ctlr->nrd; i++){
 		if((bp = ctlr->rb[i]) != nil){
 			ctlr->rb[i] = nil;
 			freeb(bp);
 		}
+	}
 	i82563replenish(ctlr);
-	csr32w(ctlr, Rxdctl, 2<<WthreshSHIFT | 2<<PthreshSHIFT);
+
+	if(ctlr->type != i82575){
+		/*
+		 * See comment above for Qenable.
+		 * Could shuffle the code?
+		 */
+		r = csr32r(ctlr, Rxdctl);
+		r &= ~(WthreshSHIFT|PthreshSHIFT);
+		r |= (2<<WthreshSHIFT)|(2<<PthreshSHIFT);
+		csr32w(ctlr, Rxdctl, r);
+	}
 
 	/*
 	 * Enable checksum offload.
@@ -1178,23 +1214,13 @@ i82563attach(Ether* edev)
 
 	ctlr = edev->ctlr;
 	qlock(&ctlr->alock);
-	if(ctlr->alloc != nil){
+	if(ctlr->attached){
 		qunlock(&ctlr->alock);
 		return;
 	}
 
 	ctlr->nrd = Nrd;
 	ctlr->ntd = Ntd;
-	ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 255);
-	if(ctlr->alloc == nil){
-		qunlock(&ctlr->alock);
-		return;
-	}
-	ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 256);
-	ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
-
-	ctlr->rb = malloc(ctlr->nrd * sizeof(Block*));
-	ctlr->tb = malloc(ctlr->ntd * sizeof(Block*));
 
 	if(waserror()){
 		while(ctlr->nrb > 0){
@@ -1207,12 +1233,23 @@ i82563attach(Ether* edev)
 		ctlr->tb = nil;
 		free(ctlr->rb);
 		ctlr->rb = nil;
-		free(ctlr->alloc);
-		ctlr->alloc = nil;
+		free(ctlr->tdba);
+		ctlr->tdba = nil;
+		free(ctlr->rdba);
+		ctlr->rdba = nil;
 		qunlock(&ctlr->alock);
 		nexterror();
 	}
 
+	if((ctlr->rdba = mallocalign(ctlr->nrd*sizeof(Rd), 128, 0, 0)) == nil)
+		error(Enomem);
+	if((ctlr->tdba = mallocalign(ctlr->ntd*sizeof(Td), 128, 0, 0)) == nil)
+		error(Enomem);
+	if((ctlr->rb = malloc(ctlr->nrd*sizeof(Block*))) == nil)
+		error(Enomem);
+	if((ctlr->tb = malloc(ctlr->ntd*sizeof(Block*))) == nil)
+		error(Enomem);
+
 	for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
 		if((bp = allocb(ctlr->rbsz + BY2PG)) == nil)
 			break;
@@ -1220,6 +1257,8 @@ i82563attach(Ether* edev)
 		freeb(bp);
 	}
 
+	ctlr->attached = 1;
+
 	snprint(name, sizeof name, "#l%dl", edev->ctlrno);
 	kproc(name, i82563lproc, edev);
 
@@ -1249,7 +1288,7 @@ i82563interrupt(Ureg*, void* arg)
 	csr32w(ctlr, Imc, ~0);
 	im = ctlr->im;
 
-	while(icr = csr32r(ctlr, Icr) & ctlr->im){
+	for(icr = csr32r(ctlr, Icr); icr & ctlr->im; icr = csr32r(ctlr, Icr)){
 		if(icr & Lsc){
 			im &= ~Lsc;
 			ctlr->lim = icr & Lsc;
@@ -1279,18 +1318,6 @@ i82563detach(Ctlr* ctlr)
 {
 	int r, timeo;
 
-	/* balance rx/tx packet buffer */
-	if(ctlr->rbsz > 8192 && (ctlr->type == i82563 || ctlr->type == i82571 ||
-	    ctlr->type == i82572)){
-		ctlr->pba = csr32r(ctlr, Pba);
-		r = ctlr->pba >> 16;
-		r += ctlr->pba & 0xffff;
-		r >>= 1;
-		csr32w(ctlr, Pba, r);
-	} else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
-		csr32w(ctlr, Pba, 14);
-	ctlr->pba = csr32r(ctlr, Pba);
-
 	/*
 	 * Perform a device reset to get the chip back to the
 	 * power-on state, followed by an EEPROM reset to read
@@ -1315,9 +1342,6 @@ i82563detach(Ctlr* ctlr)
 	if(csr32r(ctlr, Ctrl) & Devrst)
 		return -1;
 
-	r = csr32r(ctlr, Ctrl);
-	csr32w(ctlr, Ctrl, Slu|r);
-
 	r = csr32r(ctlr, Ctrlext);
 	csr32w(ctlr, Ctrlext, r|Eerst);
 	delay(1);
@@ -1339,6 +1363,26 @@ i82563detach(Ctlr* ctlr)
 	if(csr32r(ctlr, Icr))
 		return -1;
 
+	/*
+	 * Balance Rx/Tx packet buffer.
+	 * No need to set PBA register unless using jumbo, defaults to 32KB
+	 * for receive. If it is changed, then have to do a MAC reset,
+	 * and need to do that at the the right time as it will wipe stuff.
+	 */
+	if(ctlr->rbsz > 8192 && (ctlr->type == i82563 || ctlr->type == i82571 ||
+	    ctlr->type == i82572)){
+		ctlr->pba = csr32r(ctlr, Pba);
+		r = ctlr->pba >> 16;
+		r += ctlr->pba & 0xffff;
+		r >>= 1;
+		csr32w(ctlr, Pba, r);
+	} else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
+		csr32w(ctlr, Pba, 14);
+	ctlr->pba = csr32r(ctlr, Pba);
+
+	r = csr32r(ctlr, Ctrl);
+	csr32w(ctlr, Ctrl, Slu|r);
+
 	return 0;
 }
 
@@ -1426,7 +1470,7 @@ fload(Ctlr *c)
 	f.reg = vmap(io, c->pcidev->mem[1].size);
 	if(f.reg == nil)
 		return -1;
-	f.reg32 = (ulong*)f.reg;
+	f.reg32 = (void*)f.reg;
 	f.sz = f.reg32[Bfpr];
 	r = f.sz & 0x1fff;
 	if(csr32r(c, Eec) & (1<<22))
@@ -1480,10 +1524,18 @@ i82563reset(Ctlr *ctlr)
 	memset(ctlr->mta, 0, sizeof(ctlr->mta));
 	for(i = 0; i < 128; i++)
 		csr32w(ctlr, Mta + i*4, 0);
+
+	/*
+	 * Does autonegotiation affect this manual setting?
+	 * The correct values here should depend on the PBA value
+	 * and maximum frame length, no?
+	 * ctlr->fcrt[lh] are never set, so default to 0.
+	 */
 	csr32w(ctlr, Fcal, 0x00C28001);
 	csr32w(ctlr, Fcah, 0x0100);
 	csr32w(ctlr, Fct, 0x8808);
 	csr32w(ctlr, Fcttv, 0x0100);
+
 	csr32w(ctlr, Fcrtl, ctlr->fcrtl);
 	csr32w(ctlr, Fcrth, ctlr->fcrth);
 
@@ -1526,6 +1578,9 @@ i82563pci(void)
 		case 0x109a:		/*  l */
 			type = i82573;
 			break;
+		case 0x10a7:		/* 82575eb */
+			type = i82575;
+			break;
 		}
 
 		io = p->mem[0].bar & ~0x0F;
@@ -1645,6 +1700,12 @@ i82573pnp(Ether *e)
 	return pnp(e, i82573);
 }
 
+static int
+i82575pnp(Ether *e)
+{
+	return pnp(e, i82575);
+}
+
 void
 ether82563link(void)
 {
@@ -1654,5 +1715,6 @@ ether82563link(void)
 	addethercard("i82571", i82571pnp);
 	addethercard("i82572", i82572pnp);
 	addethercard("i82573", i82573pnp);
+	addethercard("i82575", i82575pnp);
 	addethercard("igbepcie", anypnp);
 }

+ 2 - 2
sys/src/9/port/netif.c

@@ -213,9 +213,9 @@ netifread(Netif *nif, Chan *c, void *a, long n, ulong offset)
 		return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);
 	case Nstatqid:
 		p = malloc(READSTR);
-		j = snprint(p, READSTR, "in: %d\n", nif->inpackets);
+		j = snprint(p, READSTR, "in: %llud\n", nif->inpackets);
 		j += snprint(p+j, READSTR-j, "link: %d\n", nif->link);
-		j += snprint(p+j, READSTR-j, "out: %d\n", nif->outpackets);
+		j += snprint(p+j, READSTR-j, "out: %llud\n", nif->outpackets);
 		j += snprint(p+j, READSTR-j, "crc errs: %d\n", nif->crcs);
 		j += snprint(p+j, READSTR-j, "overflows: %d\n", nif->overflows);
 		j += snprint(p+j, READSTR-j, "soft overflows: %d\n", nif->soverflows);

+ 2 - 2
sys/src/9/port/netif.h

@@ -87,8 +87,8 @@ struct Netif
 
 	/* statistics */
 	int	misses;
-	int	inpackets;
-	int	outpackets;
+	uvlong	inpackets;
+	uvlong	outpackets;
 	int	crcs;		/* input crc errors */
 	int	oerrs;		/* output errors */
 	int	frames;		/* framing errors */