shithub: riscv

Download patch

ref: 318fe6a702b5c118ce271b616c115648ae6d7448
parent: 5016ac0c63c3b4db1dcdace0c6136b0ac88abeea
author: cinap_lenrek <[email protected]>
date: Thu Dec 17 15:55:59 EST 2020

ether2114x: vetting the driver for pc64

the tulip driver is used in microsofts hypver-v
as the legacy ethernet adapter for pxe booting.

to make the driver work on pc64, we need to
store the Block* pointers in a separate array
instead of stuffing them into buffer address 2
of the hardware descriptor.

also, enable the driver in the pc64 kernel.

--- a/sys/src/9/pc/ether2114x.c
+++ b/sys/src/9/pc/ether2114x.c
@@ -116,12 +116,13 @@
 	Gpc		= 0x00000100,	/* General Purpose Control */
 };
 
-typedef struct Des {
-	int	status;
-	int	control;
-	ulong	addr;
-	Block*	bp;
-} Des;
+enum {
+	Dstatus,
+	Dcontrol,
+	Daddr1,
+	Daddr2,
+	Dsize,
+};
 
 enum {					/* status */
 	Of		= 0x00000001,	/* Rx: OverFlow */
@@ -227,18 +228,20 @@
 
 	Lock	lock;
 
-	Des*	rdr;			/* receive descriptor ring */
+	Block	**rbp;
+	ulong	*rdr;			/* receive descriptor ring */
 	int	nrdr;			/* size of rdr */
 	int	rdrx;			/* index into rdr */
 
 	Lock	tlock;
-	Des*	tdr;			/* transmit descriptor ring */
+	Block	*setupbp;
+	Block	**tbp;
+	ulong	*tdr;			/* transmit descriptor ring */
 	int	ntdr;			/* size of tdr */
 	int	tdrh;			/* host index into tdr */
 	int	tdri;			/* interface index into tdr */
 	int	ntq;			/* descriptors active */
 	int	ntqmax;
-	Block*	setupbp;
 
 	ulong	of;			/* receive statistics */
 	ulong	ce;
@@ -375,14 +378,13 @@
 {
 	Ctlr *ctlr;
 	Block *bp;
-	Des *des;
-	int control;
+	ulong *des, control;
 
 	ctlr = ether->ctlr;
 	while(ctlr->ntq < (ctlr->ntdr-1)){
-		if(ctlr->setupbp){
+		if(ctlr->setupbp != nil){
 			bp = ctlr->setupbp;
-			ctlr->setupbp = 0;
+			ctlr->setupbp = nil;
 			control = Ic|Set|BLEN(bp);
 		}
 		else{
@@ -391,15 +393,15 @@
 				break;
 			control = Ic|Lseg|Fseg|BLEN(bp);
 		}
-
-		ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
-		des = &ctlr->tdr[ctlr->tdrh];
-		des->bp = bp;
-		des->addr = PCIWADDR(bp->rp);
-		des->control |= control;
+		ctlr->tbp[ctlr->tdrh] = bp;
+		des = &ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)*Dsize];
+		des[Dcontrol] &= ~Ic;
+		des = &ctlr->tdr[ctlr->tdrh*Dsize];
+		des[Daddr1] = PCIWADDR(bp->rp);
+		des[Dcontrol] |= control;
 		ctlr->ntq++;
 		coherence();
-		des->status = Own;
+		des[Dstatus] = Own;
 		csr32w(ctlr, 1, 0);
 		ctlr->tdrh = NEXT(ctlr->tdrh, ctlr->ntdr);
 	}
@@ -424,9 +426,8 @@
 {
 	Ctlr *ctlr;
 	Ether *ether;
-	int len, status;
-	Des *des;
-	Block *bp;
+	Block **bpp, *bp;
+	ulong *des, status, len;
 
 	ether = arg;
 	ctlr = ether->ctlr;
@@ -459,37 +460,39 @@
 		 * Received packets.
 		 */
 		if(status & Ri){
-			des = &ctlr->rdr[ctlr->rdrx];
-			while(!(des->status & Own)){
-				if(des->status & Es){
-					if(des->status & Of)
+			for(;;){
+				des = &ctlr->rdr[ctlr->rdrx*Dsize];
+				if(des[Dstatus] & Own)
+					break;
+
+				if(des[Dstatus] & Es){
+					if(des[Dstatus] & Of)
 						ctlr->of++;
-					if(des->status & Ce)
+					if(des[Dstatus] & Ce)
 						ctlr->ce++;
-					if(des->status & Cs)
+					if(des[Dstatus] & Cs)
 						ctlr->cs++;
-					if(des->status & Tl)
+					if(des[Dstatus] & Tl)
 						ctlr->tl++;
-					if(des->status & Rf)
+					if(des[Dstatus] & Rf)
 						ctlr->rf++;
-					if(des->status & De)
+					if(des[Dstatus] & De)
 						ctlr->de++;
 				}
-				else if(bp = iallocb(Rbsz)){
-					len = ((des->status & Fl)>>16)-4;
-					des->bp->wp = des->bp->rp+len;
-					etheriq(ether, des->bp);
-					des->bp = bp;
-					des->addr = PCIWADDR(bp->rp);
+				else if((bp = iallocb(Rbsz)) != nil){
+					bpp = &ctlr->rbp[ctlr->rdrx];
+					len = ((des[Dstatus] & Fl)>>16)-4;
+					(*bpp)->wp += len;
+					etheriq(ether, *bpp);
+					*bpp = bp;
+					des[Daddr1] = PCIWADDR(bp->rp);
 				}
-
-				des->control &= Er;
-				des->control |= Rbsz;
+				des[Dcontrol] &= Er;
+				des[Dcontrol] |= Rbsz;
 				coherence();
-				des->status = Own;
+				des[Dstatus] = Own;
 
 				ctlr->rdrx = NEXT(ctlr->rdrx, ctlr->nrdr);
-				des = &ctlr->rdr[ctlr->rdrx];
 			}
 			status &= ~Ri;
 		}
@@ -529,28 +532,31 @@
 
 		ilock(&ctlr->tlock);
 		while(ctlr->ntq){
-			des = &ctlr->tdr[ctlr->tdri];
-			if(des->status & Own)
+			des = &ctlr->tdr[ctlr->tdri*Dsize];
+			if(des[Dstatus] & Own)
 				break;
 
-			if(des->status & Es){
-				if(des->status & Uf)
+			if(des[Dstatus] & Es){
+				if(des[Dstatus] & Uf)
 					ctlr->uf++;
-				if(des->status & Ec)
+				if(des[Dstatus] & Ec)
 					ctlr->ec++;
-				if(des->status & Lc)
+				if(des[Dstatus] & Lc)
 					ctlr->lc++;
-				if(des->status & Nc)
+				if(des[Dstatus] & Nc)
 					ctlr->nc++;
-				if(des->status & Lo)
+				if(des[Dstatus] & Lo)
 					ctlr->lo++;
-				if(des->status & To)
+				if(des[Dstatus] & To)
 					ctlr->to++;
 				ether->oerrs++;
 			}
+			des[Dcontrol] &= Er;
+			coherence();
 
-			freeb(des->bp);
-			des->control &= Er;
+			bpp = &ctlr->tbp[ctlr->tdri];
+			freeb(*bpp);
+			*bpp = nil;
 
 			ctlr->ntq--;
 			ctlr->tdri = NEXT(ctlr->tdri, ctlr->ntdr);
@@ -562,7 +568,7 @@
 		 * Anything left not catered for?
 		 */
 		if(status)
-			panic("#l%d: status %8.8uX", ether->ctlrno, status);
+			panic("#l%d: status %8.8luX", ether->ctlrno, status);
 	}
 }
 
@@ -570,7 +576,7 @@
 ctlrinit(Ether* ether)
 {
 	Ctlr *ctlr;
-	Des *des;
+	ulong *des;
 	Block *bp;
 	int i;
 	uchar bi[Eaddrlen*2];
@@ -584,23 +590,31 @@
 	 * create and post a setup packet to initialise
 	 * the physical ethernet address.
 	 */
-	ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(Des), 8*sizeof(ulong), 0);
-	for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
-		des->bp = iallocb(Rbsz);
-		if(des->bp == nil)
+	ctlr->rbp = xspanalloc(ctlr->nrdr*sizeof(Block*), 0, 0);
+	ctlr->rdr = xspanalloc(ctlr->nrdr*sizeof(ulong)*Dsize, 8*sizeof(ulong), 0);
+	for(i = 0; i < ctlr->nrdr; i++){
+		bp = iallocb(Rbsz);
+		if(bp == nil)
 			panic("can't allocate ethernet receive ring");
-		des->status = Own;
-		des->control = Rbsz;
-		des->addr = PCIWADDR(des->bp->rp);
+		ctlr->rbp[i] = bp;
+		des = &ctlr->rdr[i*Dsize];
+		des[Dstatus] = Own;
+		des[Dcontrol] = Rbsz;
+		des[Daddr1] = PCIWADDR(bp->rp);
 	}
-	ctlr->rdr[ctlr->nrdr-1].control |= Er;
+	ctlr->rdr[(ctlr->nrdr-1)*Dsize + Dcontrol] |= Er;
 	ctlr->rdrx = 0;
+	coherence();
 	csr32w(ctlr, 3, PCIWADDR(ctlr->rdr));
 
-	ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0);
-	ctlr->tdr[ctlr->ntdr-1].control |= Er;
+	ctlr->tbp = xspanalloc(ctlr->ntdr*sizeof(Block*), 0, 0);
+	ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(ulong)*Dsize, 8*sizeof(ulong), 0);
+	for(i = 0; i < ctlr->ntdr; i++)
+		ctlr->tbp[i] = nil;
+	ctlr->tdr[(ctlr->ntdr-1)*Dsize + Dcontrol] |= Er;
 	ctlr->tdrh = 0;
 	ctlr->tdri = 0;
+	coherence();
 	csr32w(ctlr, 4, PCIWADDR(ctlr->tdr));
 
 	/*
@@ -619,6 +633,7 @@
 		bi[i*4+2] = ether->ea[i*2+1];
 		bi[i*4+3] = ether->ea[i*2];
 	}
+
 	bp = iallocb(Eaddrlen*2*16);
 	if(bp == nil)
 		panic("can't allocate ethernet setup buffer");
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -48,7 +48,7 @@
 #	devi82365
 	cputemp		pci
 #	ether2000	ether8390
-#	ether2114x	pci
+	ether2114x	pci
 #	ether589	etherelnk3
 	ether79c970	pci
 #	ether8003	ether8390