diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-07-10 09:04:05 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-07-10 09:04:05 +0200 |
commit | b5655b7247a657bd4b590218a68ed99bbab318f6 (patch) | |
tree | c1abbf0fb9b06ca100f857581d1254be5493d237 /sys/src/9/pc/etheriwl.c | |
parent | 4ec93f94c92eec46433a962eb0f86b6f27909e6c (diff) |
wifi: adjust transmit rate on error (for etheriwl), small mkfile changes
Wnode gets two new counters: txcount and txerror
and actrate pointer that will be between minrate
and maxrate.
driver should use actrate instead of maxrate for
transmission when it can provide error feedback.
when a driver detects a transmission failed, it calls
wifitxfail() with the original packet. wifitxfail() then
reduces wn->actrate.
every 256th packet, we optimistically increase wn->actrate
before transmitting.
Diffstat (limited to 'sys/src/9/pc/etheriwl.c')
-rw-r--r-- | sys/src/9/pc/etheriwl.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c index 5aedd5017..a5c68bf4c 100644 --- a/sys/src/9/pc/etheriwl.c +++ b/sys/src/9/pc/etheriwl.c @@ -2011,7 +2011,7 @@ transmit(Wifi *wifi, Wnode *wn, Block *b) if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){ nodeid = ctlr->bssnodeid; - p = wn->maxrate; + p = wn->actrate; } if(flags & (TFlagNeedRTS|TFlagNeedCTS)){ @@ -2248,6 +2248,8 @@ receive(Ctlr *ctlr) rx = &ctlr->rx; if(ctlr->broken || rx->s == nil || rx->b == nil) return; + + bb = nil; for(hw = get16(rx->s) % Nrx; rx->i != hw; rx->i = (rx->i + 1) % Nrx){ uchar type, flags, idx, qid; u32int len; @@ -2264,14 +2266,15 @@ receive(Ctlr *ctlr) idx = *d++; qid = *d++; + if(bb != nil){ + freeb(bb); + bb = nil; + } 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); - } + tx->b[idx] = nil; /* paranoia: clear tx descriptors */ dd = tx->d + idx*Tdscsize; cc = tx->c + idx*Tcmdsize; @@ -2295,6 +2298,14 @@ receive(Ctlr *ctlr) case 24: /* add node done */ break; case 28: /* tx done */ + if(ctlr->type == Type4965){ + if(len <= 20 || d[20] == 1 || d[20] == 2) + break; + } else { + if(len <= 32 || d[32] == 1 || d[32] == 2) + break; + } + wifitxfail(ctlr->wifi, bb); break; case 102: /* calibration result (Type5000 only) */ if(len < 4) @@ -2351,9 +2362,12 @@ receive(Ctlr *ctlr) case 197: /* rx compressed ba */ break; } + /* paranoia: clear the descriptor */ memset(b->rp, 0, Rdscsize); } + if(bb != nil) + freeb(bb); csr32w(ctlr, FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7); } |