git: 9front

Download patch

ref: 411fc48b8ca8ebd2ea32d3a26b1be309c6b8ade3
parent: 8807f4a2570a00550184c1c0e2300da9e1176ab9
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Feb 9 14:12:51 EST 2013

etheriwl: fix command queue handling

we have to decrement the queue counter for all tx rings
*including* the command ring 4.

zero the command buffer for the crystal callibration
command.

--- a/sys/src/9/pc/etheriwl.c
+++ b/sys/src/9/pc/etheriwl.c
@@ -29,6 +29,7 @@
 	Rbufsize	= 4*1024,
 	Rdscsize	= 8,
 
+	Tbufsize	= 4*1024,
 	Tdscsize	= 128,
 	Tcmdsize	= 140,
 };
@@ -844,7 +845,7 @@
 txqready(void *arg)
 {
 	TXQ *q = arg;
-	return q->n < Ntx-8;
+	return q->n < Ntx;
 }
 
 static void
@@ -853,6 +854,9 @@
 	uchar *d, *c;
 	TXQ *q;
 
+	assert(qid < nelem(ctlr->tx));
+	assert(size <= Tcmdsize-4);
+
 	ilock(ctlr);
 	q = &ctlr->tx[qid];
 	while(q->n >= Ntx){
@@ -878,7 +882,6 @@
 	c[2] = q->i;
 	c[3] = qid;
 
-	assert(size <= Tcmdsize-4);
 	memmove(c+4, data, size);
 
 	size += 4;
@@ -891,8 +894,11 @@
 	put32(d, PCIWADDR(c));	d += 4;
 	put16(d, size << 4); d += 2;
 	if(block != nil){
-		put32(d, PCIWADDR(block->rp));	d += 4;
-		put16(d, BLEN(block) << 4);
+		size = BLEN(block);
+		if(size > Tbufsize)
+			size = Tbufsize;
+		put32(d, PCIWADDR(block->rp)); d += 4;
+		put16(d, size << 4);
 	}
 
 	coherence();
@@ -970,6 +976,7 @@
 	nicunlock(ctlr);
 
 	if(ctlr->type != Type5150){
+		memset(c, 0, sizeof(c));
 		c[0] = 15;	/* code */
 		c[1] = 0;	/* grup */
 		c[2] = 1;	/* ngroup */
@@ -992,14 +999,10 @@
 	memset(p = c, 0, sizeof(c));
 	*p++ = 0;	/* control (1 = update) */
 	p += 3;		/* reserved */
-
 	memmove(p, addr, 6);
 	p += 6;
-
 	p += 2;		/* reserved */
-
 	*p++ = id;	/* node id */
-
 	p++;		/* flags */
 	p += 2;		/* reserved */
 	p += 2;		/* kflags */
@@ -1028,11 +1031,11 @@
 void
 rxon(Ether *edev)
 {
+	uchar c[Tcmdsize], *p;
 	Ctlr *ctlr;
-	uchar b[128-4], *p;
 
 	ctlr = edev->ctlr;
-	memset(p = b, 0, sizeof(b));
+	memset(p = c, 0, sizeof(c));
 	memmove(p, edev->ea, 6); p += 8;	/* myaddr */
 	p += 8;					/* bssid */
 	memmove(p, edev->ea, 6); p += 8;	/* wlap */
@@ -1058,7 +1061,7 @@
 		put16(p, 0); p += 2;		/* acquisition */
 		p += 2;				/* reserved */
 	}
-	cmd(ctlr, 16, b, p - b);
+	cmd(ctlr, 16, c, p - c);
 }
 
 static struct ratetab {
@@ -1327,7 +1330,7 @@
 receive(Ctlr *ctlr)
 {
 	Block *b, *bb;
-	uchar *d;
+	uchar *d, *dd, *cc;
 	RXQ *rx;
 	TXQ *tx;
 	uint hw;
@@ -1351,12 +1354,30 @@
 		idx = *d++;
 		qid = *d++;
 
+		if((qid & 0x80) == 0 && qid < nelem(ctlr->tx)){
+			tx = &ctlr->tx[qid];
+			if(tx->n > 0){
+				bb = tx->b[idx];
+				if(bb != nil){
+					tx->b[idx] = nil;
+					freeb(bb);
+				}
+				/* paranoia: clear tx descriptors */
+				dd = tx->d + idx*Tdscsize;
+				cc = tx->c + idx*Tcmdsize;
+				memset(dd, 0, Tdscsize);
+				memset(cc, 0, Tcmdsize);
+				tx->n--;
+
+				wakeup(tx);
+			}
+		}
+
 		len &= 0x3fff;
 		if(len < 4 || type == 0)
 			continue;
 
 		len -= 4;
-
 		switch(type){
 		case 1:		/* microcontroller ready */
 			setfwinfo(ctlr, d, len);
@@ -1364,17 +1385,6 @@
 		case 24:	/* add node done */
 			break;
 		case 28:	/* tx done */
-			if(qid >= nelem(ctlr->tx))
-				break;
-			tx = &ctlr->tx[qid];
-			if(tx->n == 0)
-				break;
-			bb = tx->b[idx];
-			if(bb != nil){
-				tx->b[idx] = nil;
-				freeb(bb);
-			}
-			tx->n--;
 			break;
 		case 102:	/* calibration result (Type5000 only)
 			break;
--