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); } diff --git a/sys/src/9/pc/mkfile b/sys/src/9/pc/mkfile index b59cda33f..96ab2c623 100644 --- a/sys/src/9/pc/mkfile +++ b/sys/src/9/pc/mkfile @@ -124,6 +124,7 @@ trap.$O: /sys/include/tos.h uartaxp.$O: uartaxp.i etherm10g.$O: etherm10g2k.i etherm10g4k.i etheriwl.$O: wifi.h +etherwpi.$O: wifi.h etherrt2860.$O: wifi.h wifi.$O: wifi.h diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c index 4b9b3639d..77d2deb96 100644 --- a/sys/src/9/pc/wifi.c +++ b/sys/src/9/pc/wifi.c @@ -156,11 +156,18 @@ wifitx(Wifi *wifi, Wnode *wn, Block *b) w->seq[0] = seq; w->seq[1] = seq>>8; - if((w->fc[0] & 0x0c) != 0x00) + if((w->fc[0] & 0x0c) != 0x00){ b = wifiencrypt(wifi, wn, b); + if(b == nil) + return; + } - if(b != nil) - (*wifi->transmit)(wifi, wn, b); + if((wn->txcount++ & 255) == 255){ + if(wn->actrate != nil && wn->actrate < wn->maxrate) + wn->actrate++; + } + + (*wifi->transmit)(wifi, wn, b); } static Wnode* @@ -196,6 +203,23 @@ nodelookup(Wifi *wifi, uchar *bssid, int new) 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* putrates(uchar *p, uchar *rates) { @@ -417,6 +441,7 @@ recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len) break; } } + wn->actrate = wn->maxrate; } break; case 3: /* DSPARAMS */ diff --git a/sys/src/9/pc/wifi.h b/sys/src/9/pc/wifi.h index f1311c05a..d9a8514a6 100644 --- a/sys/src/9/pc/wifi.h +++ b/sys/src/9/pc/wifi.h @@ -39,6 +39,10 @@ struct Wnode uchar *minrate; /* pointers into wifi->rates */ uchar *maxrate; + uchar *actrate; + + ulong txcount; /* statistics for rate adaption */ + ulong txerror; /* stuff from beacon */ int ival; @@ -87,6 +91,7 @@ struct Wifipkt Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*)); void wifiiq(Wifi*, Block*); int wifihdrlen(Wifipkt*); +void wifitxfail(Wifi*, Block*); long wifistat(Wifi*, void*, long, ulong); long wifictl(Wifi*, void*, long); diff --git a/sys/src/9/pc64/mkfile b/sys/src/9/pc64/mkfile index 3027eaaa5..b9ab0efdd 100644 --- a/sys/src/9/pc64/mkfile +++ b/sys/src/9/pc64/mkfile @@ -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 REPCH=`{echo $PCHEADERS | sed 's/\.h//g; s/ /|/g'} -^($REPCH)\.h:R: '../pc/\1.h' +^($REPCH)\.h:R: ../pc/\1.h cp $prereq . REPCC=`{../port/mkfilelist ../pc} @@ -122,6 +122,7 @@ usbehci.$O usbehcipc.$O: usbehci.h trap.$O: /sys/include/tos.h ethermii.$O: ethermii.h etheriwl.$O: wifi.h +etherwpi.$O: wifi.h etherrt2860.$O: wifi.h wifi.$O: wifi.h diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64 index 67fae1818..3db977e06 100644 --- a/sys/src/9/pc64/pc64 +++ b/sys/src/9/pc64/pc64 @@ -69,7 +69,7 @@ link # etherwavelan wavelan devi82365 cis pci etheriwl pci wifi etherwpi pci wifi -# etherrt2860 pci wifi + etherrt2860 pci wifi ethervirtio pci ethermedium # pcmciamodem diff --git a/sys/src/9/port/portmkfile b/sys/src/9/port/portmkfile index 01db7acf9..c16cf9c93 100644 --- a/sys/src/9/port/portmkfile +++ b/sys/src/9/port/portmkfile @@ -1,9 +1,9 @@ PORTFILES=`{../port/mkfilelist ../port} -^($PORTFILES)\.$O:R: '../port/\1.c' +^($PORTFILES)\.$O:R: ../port/\1.c $CC $CFLAGS -I. ../port/$stem1.c 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 %.$O: %.s