shithub: riscv

Download patch

ref: 962ec8cfb1bb33f8eefaee5520e88fbee699ff2e
parent: 9a7e90d36117e223c8066bdc9613b316bb366e92
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Tue Aug 30 05:08:55 EDT 2011

ether8169: sometimes transmits got missed. kicking the poll bit on each transmit fixes the problem

--- a/sys/src/9/pc/ether8169.c
+++ b/sys/src/9/pc/ether8169.c
@@ -670,7 +670,7 @@
 	 * Transmitter.
 	 */
 	memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
-	ctlr->tdh = ctlr->tdt = 0;
+	ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
 	ctlr->td[ctlr->ntd-1].control = Eor;
 
 	/*
@@ -759,12 +759,9 @@
 
 	/*
 	 * Interrupts.
-	 * Disable Tdu|Tok for now, the transmit routine will tidy.
-	 * Tdu means the NIC ran out of descriptors to send, so it
-	 * doesn't really need to ever be on.
 	 */
 	csr32w(ctlr, Timerint, 0);
-	ctlr->imr = Serr|Timeout|Fovw|Punlc|Rdu|Ter|Rer|Rok;
+	ctlr->imr = Serr|Timeout|Fovw|Punlc|Rdu|Ter|Rer|Rok|Tdu;
 	csr16w(ctlr, Imr, ctlr->imr);
 
 	/*
@@ -890,7 +887,7 @@
 	D *d;
 	Block *bp;
 	Ctlr *ctlr;
-	int control, x;
+	int x;
 
 	ctlr = edev->ctlr;
 
@@ -897,15 +894,10 @@
 	ilock(&ctlr->tlock);
 	for(x = ctlr->tdh; ctlr->ntq > 0; x = NEXT(x, ctlr->ntd)){
 		d = &ctlr->td[x];
-		if((control = d->control) & Own)
+		if(d->control & Own)
 			break;
 
 		/*
-		 * Check errors and log here.
-		 */
-		USED(control);
-
-		/*
 		 * Free it up.
 		 * Need to clean the descriptor here? Not really.
 		 * Simple freeb for now (no chain and freeblist).
@@ -913,7 +905,6 @@
 		 */
 		freeb(ctlr->tb[x]);
 		ctlr->tb[x] = nil;
-		d->control &= Eor;
 
 		ctlr->ntq--;
 	}
@@ -927,20 +918,23 @@
 		d = &ctlr->td[x];
 		d->addrlo = PCIWADDR(bp->rp);
 		d->addrhi = 0;
-		ctlr->tb[x] = bp;
 		coherence();
-		d->control |= Own | Fs | Ls | BLEN(bp);
+		ctlr->tb[x] = bp;
+		d->control = (d->control & Eor) | Own | Fs | Ls | BLEN(bp);
 
 		x = NEXT(x, ctlr->ntd);
 		ctlr->ntq++;
 	}
-	if(x != ctlr->tdt){
+	if(x != ctlr->tdt)
 		ctlr->tdt = x;
-		csr8w(ctlr, Tppoll, Npq);
-	}
 	else if(ctlr->ntq >= (ctlr->ntd-1))
 		ctlr->txdu++;
 
+	if(ctlr->ntq > 0){
+		coherence();
+		csr8w(ctlr, Tppoll, Npq);
+	}
+
 	iunlock(&ctlr->tlock);
 }
 
@@ -1029,6 +1023,7 @@
 		csr16w(ctlr, Isr, isr);
 		if((isr & ctlr->imr) == 0)
 			break;
+
 		if(isr & (Fovw|Punlc|Rdu|Rer|Rok)){
 			rtl8169receive(edev);
 			if(!(isr & (Punlc|Rok)))