From cc8e20d6378dd8d97c0864fa6c4d7b890bbe4540 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 11 Mar 2003 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2003-03-11 --- bitsy/wavelan.c | 119 +++++++++++++++++++++++++++++++++++++----------- ip/ipv6.c | 2 +- 2 files changed, 94 insertions(+), 27 deletions(-) diff --git a/bitsy/wavelan.c b/bitsy/wavelan.c index ae1135e61c60a410fa2f772c84744d145602c61a..1f2ded63898d1b6755cc0967e4dd725cc6eb48c7 100644 --- a/bitsy/wavelan.c +++ b/bitsy/wavelan.c @@ -1,5 +1,5 @@ /* - Lucent Wavelan IEEE 802.11 pcmcia. + Lucent Wavelan IEEE 802.11 pcmcia. There is almost no documentation for the card. the driver is done using both the FreeBSD, Linux and original Plan 9 drivers as `documentation'. @@ -28,6 +28,11 @@ #include "etherif.h" #include "wavelan.h" +enum +{ + MSperTick= 50, /* ms between ticks of kproc */ +}; + /* * When we're using a PCI device and memory-mapped I/O, * the registers are spaced out as though each takes 32 bits, @@ -381,7 +386,7 @@ w_enable(Ether* ether) ltv_outs(ctlr, WTyp_Prom, (ether->prom?1:0)); - if(ctlr->hascrypt){ + if(ctlr->hascrypt && ctlr->crypt){ ltv_outs(ctlr, WTyp_Crypt, ctlr->crypt); ltv_outs(ctlr, WTyp_TxKey, ctlr->txkey); w_outltv(ctlr, &ctlr->keys); @@ -528,30 +533,90 @@ w_txdone(Ctlr* ctlr, int sts) ctlr->ntx++; } -static int -w_stats(Ctlr* ctlr) +/* save the stats info in the ctlr struct */ +static void +w_stats(Ctlr* ctlr, int len) { - int i, rc, sp; - Wltv ltv; + int i, rc; ulong* p = (ulong*)&ctlr->WStats; ulong* pend = (ulong*)&ctlr->end; + for (i = 0; i < len && p < pend; i++){ + rc = csr_ins(ctlr, WR_Data1); + if(rc > 0xf000) + rc = ~rc & 0xffff; + p[i] += rc; + } +} + +/* send the base station scan info to any readers */ +static void +w_scaninfo(Ether* ether, Ctlr *ctlr, int len) +{ + int i, j; + Netfile **ep, *f, **fp; + Block *bp; + WScan *wsp; + + for (i = 0; i < len ; i++) + ctlr->scanbuf[i] = csr_ins(ctlr, WR_Data1); + + len *= 2; + i = ether->scan; + ep = ðer->f[Ntypes]; + for(fp = ether->f; fp < ep && i > 0; fp++){ + f = *fp; + if(f == nil || f->scan == 0) + continue; + + bp = iallocb(2048); + if(bp == nil) + break; + for(j = 0; j < len/(2*25); j++){ + wsp = (WScan*)(&ctlr->scanbuf[j*25]); + if(wsp->ssid_len > 32) + wsp->ssid_len = 32; + bp->wp += snprint((char*)bp->wp, 2048, + "ssid=%.*s;bssid=%E;signal=%d;noise=%d;chan=%d%s\n", + wsp->ssid_len, wsp->ssid, wsp->bssid, wsp->signal, + wsp->noise, wsp->chan, (wsp->capinfo&(1<<4))?";wep":""); + } + qpass(f->in, bp); + i--; + } +} + +static int +w_info(Ether *ether, Ctlr* ctlr) +{ + int sp; + Wltv ltv; + sp = csr_ins(ctlr, WR_InfoId); ltv.len = ltv.type = 0; w_read(ctlr, sp, 0, <v, 4); - if(ltv.type == WTyp_Stats){ - ltv.len--; - for (i = 0; i < ltv.len && p < pend; i++){ - rc = csr_ins(ctlr, WR_Data1); - if(rc > 0xf000) - rc = ~rc & 0xffff; - p[i] += rc; - } + ltv.len--; + switch(ltv.type){ + case WTyp_Stats: + w_stats(ctlr, ltv.len); + return 0; + case WTyp_Scan: + w_scaninfo(ether, ctlr, ltv.len); return 0; } return -1; } +/* set scanning interval */ +static void +w_scanbs(void *a, uint secs) +{ + Ether *ether = a; + Ctlr* ctlr = (Ctlr*) ether->ctlr; + + ctlr->scanticks = secs*(1000/MSperTick); +} + static void w_intr(Ether *ether) { @@ -588,7 +653,7 @@ w_intr(Ether *ether) } if(rc & WInfoEv){ ctlr->ninfo++; - w_stats(ctlr); + w_info(ether, ctlr); csr_ack(ctlr, WInfoEv); } if(rc & WTxErrEv){ @@ -614,7 +679,7 @@ w_timer(void* arg) ctlr->timerproc = up; for(;;){ - tsleep(&ctlr->timer, return0, 0, 50); + tsleep(&ctlr->timer, return0, 0, MSperTick); ctlr = (Ctlr*)ether->ctlr; if(ctlr == 0) break; @@ -656,6 +721,10 @@ w_timer(void* arg) if((ctlr->ticks % 120) == 0) if(ctlr->txbusy == 0) w_cmd(ctlr, WCmdEnquire, WTyp_Stats); + if(ctlr->scanticks > 0) + if((ctlr->ticks % ctlr->scanticks) == 0) + if(ctlr->txbusy == 0) + w_cmd(ctlr, WCmdEnquire, WTyp_Scan); } iunlock(ctlr); } @@ -793,7 +862,7 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset) k = ((ctlr->state & Attached) ? "attached" : "not attached"); PRINTSTAT("Card %s", k); k = ((ctlr->state & Power) ? "on" : "off"); - PRINTSTAT("PCardower %s", k); + PRINTSTAT(", power %s", k); k = ((ctlr->txbusy)? ", txbusy" : ""); PRINTSTAT("%s\n", k); @@ -823,7 +892,7 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset) PRINTSTAT("Channel: %d\n", ltv_ins(ctlr, WTyp_Chan)); PRINTSTAT("AP density: %d\n", ltv_ins(ctlr, WTyp_ApDens)); PRINTSTAT("Promiscuous mode: %d\n", ltv_ins(ctlr, WTyp_Prom)); - if(i == 3) + if(i == WPTypeAdHoc) PRINTSTAT("SSID name: %s\n", ltv_inname(ctlr, WTyp_NetName)); else { Wltv ltv; @@ -890,11 +959,8 @@ w_option(Ctlr* ctlr, char* buf, long n) Cmdbuf *cb; r = 0; - print("here\n"); - cb = parsecmd(buf, n); - for (i = 0; i < cb->nf; i++) - iprint("cb %s\n", cb->f[i]); + cb = parsecmd(buf, n); if(cb->nf < 2) r = -1; else if(cistrcmp(cb->f[0], "essid") == 0){ @@ -902,7 +968,7 @@ w_option(Ctlr* ctlr, char* buf, long n) p = ""; else p = cb->f[1]; - if(ctlr->ptype == 3){ + if(ctlr->ptype == WPTypeAdHoc){ memset(ctlr->netname, 0, sizeof(ctlr->netname)); strncpy(ctlr->netname, p, WNameLen); } @@ -1128,11 +1194,12 @@ wavelanreset(Ether* ether, Ctlr *ctlr) ether->power = w_power; ether->promiscuous = w_promiscuous; ether->multicast = w_multicast; + ether->scanbs = w_scanbs; ether->arg = ether; - iprint("#l%d: irq %ld port %lx type %s", + DEBUG("#l%d: irq %ld port %lx type %s", ether->ctlrno, ether->intnum, ether->ports[0].port, ether->type); - iprint(" %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX\n", + DEBUG(" %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX\n", ether->ea[0], ether->ea[1], ether->ea[2], ether->ea[3], ether->ea[4], ether->ea[5]); @@ -1143,8 +1210,8 @@ char* wavenames[] = { "WaveLAN/IEEE", "TrueMobile 1150", "Instant Wireless ; Network PC CARD", + "Instant Wireless Network PC Card", "Avaya Wireless PC Card", "AirLancer MC-11", nil, }; - diff --git a/ip/ipv6.c b/ip/ipv6.c index fa20d618beafb2461a985b591643139efdc4a27a..03f5e2df932cfdc0a2d22021954a1263d4975579 100644 --- a/ip/ipv6.c +++ b/ip/ipv6.c @@ -173,7 +173,7 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c) } if(len >= IP_MAX){ - print("len > IP_MAX, free\n"); +// print("len > IP_MAX, free\n"); ip->stats[OutDiscards]++; netlog(f, Logip, "exceeded ip max size %I\n", eh->dst); goto free;