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.
This commit is contained in:
cinap_lenrek 2015-07-10 09:04:05 +02:00
parent 4ec93f94c9
commit b5655b7247
7 changed files with 58 additions and 12 deletions

View file

@ -2011,7 +2011,7 @@ transmit(Wifi *wifi, Wnode *wn, Block *b)
if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){ if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
nodeid = ctlr->bssnodeid; nodeid = ctlr->bssnodeid;
p = wn->maxrate; p = wn->actrate;
} }
if(flags & (TFlagNeedRTS|TFlagNeedCTS)){ if(flags & (TFlagNeedRTS|TFlagNeedCTS)){
@ -2248,6 +2248,8 @@ receive(Ctlr *ctlr)
rx = &ctlr->rx; rx = &ctlr->rx;
if(ctlr->broken || rx->s == nil || rx->b == nil) if(ctlr->broken || rx->s == nil || rx->b == nil)
return; return;
bb = nil;
for(hw = get16(rx->s) % Nrx; rx->i != hw; rx->i = (rx->i + 1) % Nrx){ for(hw = get16(rx->s) % Nrx; rx->i != hw; rx->i = (rx->i + 1) % Nrx){
uchar type, flags, idx, qid; uchar type, flags, idx, qid;
u32int len; u32int len;
@ -2264,14 +2266,15 @@ receive(Ctlr *ctlr)
idx = *d++; idx = *d++;
qid = *d++; qid = *d++;
if(bb != nil){
freeb(bb);
bb = nil;
}
if((qid & 0x80) == 0 && qid < nelem(ctlr->tx)){ if((qid & 0x80) == 0 && qid < nelem(ctlr->tx)){
tx = &ctlr->tx[qid]; tx = &ctlr->tx[qid];
if(tx->n > 0){ if(tx->n > 0){
bb = tx->b[idx]; bb = tx->b[idx];
if(bb != nil){ tx->b[idx] = nil;
tx->b[idx] = nil;
freeb(bb);
}
/* paranoia: clear tx descriptors */ /* paranoia: clear tx descriptors */
dd = tx->d + idx*Tdscsize; dd = tx->d + idx*Tdscsize;
cc = tx->c + idx*Tcmdsize; cc = tx->c + idx*Tcmdsize;
@ -2295,6 +2298,14 @@ receive(Ctlr *ctlr)
case 24: /* add node done */ case 24: /* add node done */
break; break;
case 28: /* tx done */ 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; break;
case 102: /* calibration result (Type5000 only) */ case 102: /* calibration result (Type5000 only) */
if(len < 4) if(len < 4)
@ -2351,9 +2362,12 @@ receive(Ctlr *ctlr)
case 197: /* rx compressed ba */ case 197: /* rx compressed ba */
break; break;
} }
/* paranoia: clear the descriptor */ /* paranoia: clear the descriptor */
memset(b->rp, 0, Rdscsize); memset(b->rp, 0, Rdscsize);
} }
if(bb != nil)
freeb(bb);
csr32w(ctlr, FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7); csr32w(ctlr, FhRxWptr, ((hw+Nrx-1) % Nrx) & ~7);
} }

View file

@ -124,6 +124,7 @@ trap.$O: /sys/include/tos.h
uartaxp.$O: uartaxp.i uartaxp.$O: uartaxp.i
etherm10g.$O: etherm10g2k.i etherm10g4k.i etherm10g.$O: etherm10g2k.i etherm10g4k.i
etheriwl.$O: wifi.h etheriwl.$O: wifi.h
etherwpi.$O: wifi.h
etherrt2860.$O: wifi.h etherrt2860.$O: wifi.h
wifi.$O: wifi.h wifi.$O: wifi.h

View file

@ -156,11 +156,18 @@ wifitx(Wifi *wifi, Wnode *wn, Block *b)
w->seq[0] = seq; w->seq[0] = seq;
w->seq[1] = seq>>8; w->seq[1] = seq>>8;
if((w->fc[0] & 0x0c) != 0x00) if((w->fc[0] & 0x0c) != 0x00){
b = wifiencrypt(wifi, wn, b); b = wifiencrypt(wifi, wn, b);
if(b == nil)
return;
}
if(b != nil) if((wn->txcount++ & 255) == 255){
(*wifi->transmit)(wifi, wn, b); if(wn->actrate != nil && wn->actrate < wn->maxrate)
wn->actrate++;
}
(*wifi->transmit)(wifi, wn, b);
} }
static Wnode* static Wnode*
@ -196,6 +203,23 @@ nodelookup(Wifi *wifi, uchar *bssid, int new)
return nn; return nn;
} }
void
wifitxfail(Wifi *wifi, Block *b)
{
Wifipkt *w;
Wnode *wn;
if(b == nil)
return;
w = (Wifipkt*)b->rp;
wn = nodelookup(wifi, w->a1, 0);
if(wn == nil)
return;
wn->txerror++;
if(wn->actrate != nil && wn->actrate > wn->minrate)
wn->actrate--;
}
static uchar* static uchar*
putrates(uchar *p, uchar *rates) putrates(uchar *p, uchar *rates)
{ {
@ -417,6 +441,7 @@ recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len)
break; break;
} }
} }
wn->actrate = wn->maxrate;
} }
break; break;
case 3: /* DSPARAMS */ case 3: /* DSPARAMS */

View file

@ -39,6 +39,10 @@ struct Wnode
uchar *minrate; /* pointers into wifi->rates */ uchar *minrate; /* pointers into wifi->rates */
uchar *maxrate; uchar *maxrate;
uchar *actrate;
ulong txcount; /* statistics for rate adaption */
ulong txerror;
/* stuff from beacon */ /* stuff from beacon */
int ival; int ival;
@ -87,6 +91,7 @@ struct Wifipkt
Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*)); Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*));
void wifiiq(Wifi*, Block*); void wifiiq(Wifi*, Block*);
int wifihdrlen(Wifipkt*); int wifihdrlen(Wifipkt*);
void wifitxfail(Wifi*, Block*);
long wifistat(Wifi*, void*, long, ulong); long wifistat(Wifi*, void*, long, ulong);
long wifictl(Wifi*, void*, long); long wifictl(Wifi*, void*, long);

View file

@ -86,7 +86,7 @@ install:V: $p$CONF
PCHEADERS=wifi.h usbehci.h screen.h etherif.h ethermii.h mp.h io.h ahci.h PCHEADERS=wifi.h usbehci.h screen.h etherif.h ethermii.h mp.h io.h ahci.h
REPCH=`{echo $PCHEADERS | sed 's/\.h//g; s/ /|/g'} REPCH=`{echo $PCHEADERS | sed 's/\.h//g; s/ /|/g'}
^($REPCH)\.h:R: '../pc/\1.h' ^($REPCH)\.h:R: ../pc/\1.h
cp $prereq . cp $prereq .
REPCC=`{../port/mkfilelist ../pc} REPCC=`{../port/mkfilelist ../pc}
@ -122,6 +122,7 @@ usbehci.$O usbehcipc.$O: usbehci.h
trap.$O: /sys/include/tos.h trap.$O: /sys/include/tos.h
ethermii.$O: ethermii.h ethermii.$O: ethermii.h
etheriwl.$O: wifi.h etheriwl.$O: wifi.h
etherwpi.$O: wifi.h
etherrt2860.$O: wifi.h etherrt2860.$O: wifi.h
wifi.$O: wifi.h wifi.$O: wifi.h

View file

@ -69,7 +69,7 @@ link
# etherwavelan wavelan devi82365 cis pci # etherwavelan wavelan devi82365 cis pci
etheriwl pci wifi etheriwl pci wifi
etherwpi pci wifi etherwpi pci wifi
# etherrt2860 pci wifi etherrt2860 pci wifi
ethervirtio pci ethervirtio pci
ethermedium ethermedium
# pcmciamodem # pcmciamodem

View file

@ -1,9 +1,9 @@
PORTFILES=`{../port/mkfilelist ../port} PORTFILES=`{../port/mkfilelist ../port}
^($PORTFILES)\.$O:R: '../port/\1.c' ^($PORTFILES)\.$O:R: ../port/\1.c
$CC $CFLAGS -I. ../port/$stem1.c $CC $CFLAGS -I. ../port/$stem1.c
IPFILES=`{../port/mkfilelist ../ip} IPFILES=`{../port/mkfilelist ../ip}
^($IPFILES)\.$O:R: '../ip/\1.c' ../ip/ip.h ../ip/ipv6.h ^($IPFILES)\.$O:R: ../ip/\1.c ../ip/ip.h ../ip/ipv6.h
$CC $CFLAGS -I. ../ip/$stem1.c $CC $CFLAGS -I. ../ip/$stem1.c
%.$O: %.s %.$O: %.s