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:
parent
4ec93f94c9
commit
b5655b7247
7 changed files with 58 additions and 12 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue