From cf9231140406536603da3b1517c38e4e159e8921 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 18 Jan 2003 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2003-01-18 --- pc/uarti8250.c | 54 +++++++++++++++---------------- pc/wavelan.c | 86 ++++++++++++++++++++++++++++++++++++-------------- pc/wavelan.h | 7 ++-- port/netif.c | 19 +++++++++++ port/netif.h | 3 ++ 5 files changed, 114 insertions(+), 55 deletions(-) diff --git a/pc/uarti8250.c b/pc/uarti8250.c index 795c4ffb2e025110349a93590c401ba2c0bba825..1196129891c3d31a793ed9649331755f42b8b9be 100644 --- a/pc/uarti8250.c +++ b/pc/uarti8250.c @@ -10,32 +10,32 @@ * 8250 UART and compatibles. */ enum { - Uart0 = 0x3F8, /* COM1 */ + Uart0 = 0x3F8, /* COM1 */ Uart0IRQ = 4, - Uart1 = 0x2F8, /* COM2 */ + Uart1 = 0x2F8, /* COM2 */ Uart1IRQ = 3, UartFREQ = 1843200, }; enum { /* I/O ports */ - Rbr = 0, /* Receiver Buffer (RO) */ - Thr = 0, /* Transmitter Holding (WO) */ - Ier = 1, /* Interrupt Enable */ - Iir = 2, /* Interrupt Identification (RO) */ - Fcr = 2, /* FIFO Control (WO) */ - Lcr = 3, /* Line Control */ - Mcr = 4, /* Modem Control */ - Lsr = 5, /* Line Status */ - Msr = 6, /* Modem Status */ - Scr = 7, /* Scratch Pad */ - Dll = 0, /* Divisor Latch LSB */ - Dlm = 1, /* Divisor Latch MSB */ + Rbr = 0, /* Receiver Buffer (RO) */ + Thr = 0, /* Transmitter Holding (WO) */ + Ier = 1, /* Interrupt Enable */ + Iir = 2, /* Interrupt Identification (RO) */ + Fcr = 2, /* FIFO Control (WO) */ + Lcr = 3, /* Line Control */ + Mcr = 4, /* Modem Control */ + Lsr = 5, /* Line Status */ + Msr = 6, /* Modem Status */ + Scr = 7, /* Scratch Pad */ + Dll = 0, /* Divisor Latch LSB */ + Dlm = 1, /* Divisor Latch MSB */ }; enum { /* Ier */ Erda = 0x01, /* Enable Received Data Available */ - Ethre = 0x02, /* Enable Thr Empty */ + Ethre = 0x02, /* Enable Thr Empty */ Erls = 0x04, /* Enable Receiver Line Status */ Ems = 0x08, /* Enable Modem Status */ }; @@ -47,18 +47,18 @@ enum { /* Iir */ Irda = 0x04, /* Received Data Available */ Irls = 0x06, /* Receiver Line Status */ Ictoi = 0x0C, /* Character Time-out Indication */ - IirMASK = 0x3F, + IirMASK = 0x3F, Ife = 0xC0, /* FIFOs enabled */ }; enum { /* Fcr */ - FIFOena = 0x01, /* FIFO enable */ + FIFOena = 0x01, /* FIFO enable */ FIFOrclr = 0x02, /* clear Rx FIFO */ FIFOtclr = 0x04, /* clear Tx FIFO */ - FIFO1 = 0x00, /* Rx FIFO trigger level 1 byte */ - FIFO4 = 0x40, /* 4 bytes */ - FIFO8 = 0x80, /* 8 bytes */ - FIFO14 = 0xC0, /* 14 bytes */ + FIFO1 = 0x00, /* Rx FIFO trigger level 1 byte */ + FIFO4 = 0x40, /* 4 bytes */ + FIFO8 = 0x80, /* 8 bytes */ + FIFO14 = 0xC0, /* 14 bytes */ }; enum { /* Lcr */ @@ -66,7 +66,7 @@ enum { /* Lcr */ Wls6 = 0x01, /* 6 bits/byte */ Wls7 = 0x02, /* 7 bits/byte */ Wls8 = 0x03, /* 8 bits/byte */ - WlsMASK = 0x03, + WlsMASK = 0x03, Stb = 0x04, /* 2 stop bits */ Pen = 0x08, /* Parity Enable */ Eps = 0x10, /* Even Parity Select */ @@ -90,15 +90,15 @@ enum { /* Lsr */ Fe = 0x08, /* Framing Error */ Bi = 0x10, /* Break Interrupt */ Thre = 0x20, /* Thr Empty */ - Temt = 0x40, /* Tramsmitter Empty */ - FIFOerr = 0x80, /* error in receiver FIFO */ + Temt = 0x40, /* Tramsmitter Empty */ + FIFOerr = 0x80, /* error in receiver FIFO */ }; enum { /* Msr */ Dcts = 0x01, /* Delta Cts */ Ddsr = 0x02, /* Delta Dsr */ Teri = 0x04, /* Trailing Edge of Ri */ - Ddcd = 0x08, /* Delta Dcd */ + Ddcd = 0x08, /* Delta Dcd */ Cts = 0x10, /* Clear To Send */ Dsr = 0x20, /* Data Set Ready */ Ri = 0x40, /* Ring Indicator */ @@ -445,7 +445,6 @@ i8250interrupt(Ureg*, void* arg) Ctlr *ctlr; Uart *uart; int iir, lsr, old, r; -int nin; uart = arg; @@ -487,7 +486,6 @@ int nin; * overrun is an indication that something has * already been tossed. */ -nin = 0; while((lsr = csr8r(ctlr, Lsr)) & Dr){ if(lsr & Oe) uart->oerr++; @@ -498,9 +496,7 @@ nin = 0; r = csr8r(ctlr, Rbr); if(!(lsr & (Bi|Fe|Pe))) uartrecv(uart, r); - nin++; } -if(nin == 0) print("%ux but no data\n", iir); break; default: diff --git a/pc/wavelan.c b/pc/wavelan.c index 6fe092833d6f8f4b184b67989203a345875ad486..f4689bc2fc4ff92cf70f1d04aca15dd1c52c171a 100644 --- a/pc/wavelan.c +++ b/pc/wavelan.c @@ -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, @@ -528,6 +533,7 @@ w_txdone(Ctlr* ctlr, int sts) ctlr->ntx++; } +/* save the stats info in the ctlr struct */ static void w_stats(Ctlr* ctlr, int len) { @@ -543,18 +549,45 @@ w_stats(Ctlr* ctlr, int len) } } +/* send the base station scan info to any readers */ static void -w_scan(Ctlr* ctlr, int len) +w_scaninfo(Ether* ether, Ctlr *ctlr, int len) { - int i; + 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); - for (i = 0; i < len && i < nelem(ctlr->wscan); i++) - ctlr->wscan[i] = csr_ins(ctlr, WR_Data1); - ctlr->nwscan = i; + 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(Ctlr* ctlr) +w_info(Ether *ether, Ctlr* ctlr) { int sp; Wltv ltv; @@ -568,14 +601,22 @@ w_info(Ctlr* ctlr) w_stats(ctlr, ltv.len); return 0; case WTyp_Scan: - print("calling w_scan %d\n", ltv.len); - w_scan(ctlr, ltv.len); + w_scaninfo(ether, ctlr, ltv.len); return 0; } - print("got type %d\n", ltv.type); 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) { @@ -593,7 +634,6 @@ w_intr(Ether *ether) rc = csr_ins(ctlr, WR_EvSts); csr_ack(ctlr, ~WEvs); // Not interested in them -print("intr %ux\n", rc); if(rc & WRXEv){ w_rxdone(ether); csr_ack(ctlr, WRXEv); @@ -613,7 +653,7 @@ print("intr %ux\n", rc); } if(rc & WInfoEv){ ctlr->ninfo++; - w_info(ctlr); + w_info(ether, ctlr); csr_ack(ctlr, WInfoEv); } if(rc & WTxErrEv){ @@ -639,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; @@ -664,10 +704,10 @@ w_timer(void* arg) // the card frames in the wrong way; due to the // lack of documentation I cannot know. -// if(csr_ins(ctlr, WR_EvSts)&WEvs){ -// ctlr->tickintr++; -// w_intr(ether); -// } + if(csr_ins(ctlr, WR_EvSts)&WEvs){ + ctlr->tickintr++; + w_intr(ether); + } if((ctlr->ticks % 10) == 0) { if(ctlr->txtmout && --ctlr->txtmout == 0){ @@ -681,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); } @@ -796,7 +840,7 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset) if(n == 0 || offset != 0) return 0; - p = malloc(2*READSTR); + p = malloc(READSTR); l = 0; PRINTSTAT("Signal: %d\n", ctlr->signal-149); @@ -875,11 +919,6 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset) PRINTSTAT("Transmit key id: %d\n", txid); } } - if(ctlr->nwscan){ - for(i = 0; i < ctlr->nwscan; i++) - PRINTSTAT("ws: %4.4ux\n", ctlr->wscan[i]); - ctlr->nwscan = 0; - } iunlock(ctlr); PRINTSTAT("ntxuframes: %lud\n", ctlr->ntxuframes); @@ -1110,7 +1149,7 @@ wavelanreset(Ether* ether, Ctlr *ctlr) ctlr->keys.len = sizeof(WKey)*WNKeys/2 + 1; ctlr->keys.type = WTyp_Keys; if(ctlr->hascrypt = ltv_ins(ctlr, WTyp_HasCrypt)) - ctlr->crypt = 0; + ctlr->crypt = 1; *ctlr->netname = *ctlr->wantname = 0; strcpy(ctlr->nodename, "Plan 9 STA"); @@ -1155,6 +1194,7 @@ wavelanreset(Ether* ether, Ctlr *ctlr) ether->power = w_power; ether->promiscuous = w_promiscuous; ether->multicast = w_multicast; + ether->scanbs = w_scanbs; ether->arg = ether; DEBUG("#l%d: irq %ld port %lx type %s", diff --git a/pc/wavelan.h b/pc/wavelan.h index fd1449f28bcfdd97038a8b9042af5b57e1bb036f..dce0fe74fea8cdf4366ea65dddcfcad89d1cbf65 100644 --- a/pc/wavelan.h +++ b/pc/wavelan.h @@ -8,6 +8,7 @@ enum { WTyp_Stats = 0xf100, WTyp_Scan = 0xf101, + WTyp_Link = 0xf200, WTyp_Ptype = 0xfc00, WTyp_Mac = 0xfc01, WTyp_WantName = 0xfc02, @@ -173,7 +174,7 @@ struct WScan ushort interval; /* beacon transmit interval */ ushort capinfo; /* capability bits (0-ess, 1-ibss, 4-privacy [wep]) */ ushort ssid_len; /* ssid length */ - uchar ssid[WNameLen]; /* ssid (ap name) */ + char ssid[WNameLen]; /* ssid (ap name) */ }; struct WFrame @@ -280,6 +281,7 @@ struct Ctlr int pmwait; Proc *timerproc; + int scanticks; char netname[WNameLen]; char wantname[WNameLen]; @@ -304,8 +306,7 @@ struct Ctlr Stats; WStats; - int nwscan; - ushort wscan[128]; + ushort scanbuf[25*4]; // buffer for base station scan info }; extern char* wavenames[]; diff --git a/port/netif.c b/port/netif.c index b9b757059e651f30a0a3985c34f3a6cd3dbfde78..d10d8b34285eb282041c2e88d85709512a8be495 100644 --- a/port/netif.c +++ b/port/netif.c @@ -308,6 +308,17 @@ netifwrite(Netif *nif, Chan *c, void *a, long n) f->prom = 1; nif->prom++; } + } else if((p = matchtoken(buf, "scanbs")) != 0){ + /* scan for base stations */ + if(f->scan == 0){ + type = atoi(p); + if(type < 5) + type = 5; + if(nif->scanbs != nil) + nif->scanbs(nif->arg, type); + f->scan = type; + nif->scan++; + } } else if(matchtoken(buf, "bridge")){ f->bridge = 1; } else if(matchtoken(buf, "headersonly")){ @@ -389,6 +400,14 @@ netifclose(Netif *nif, Chan *c) qunlock(nif); f->prom = 0; } + if(f->scan){ + qlock(nif); + if(--(nif->scan) == 0 && nif->scanbs != nil) + nif->scanbs(nif->arg, 0); + qunlock(nif); + f->prom = 0; + f->scan = 0; + } if(f->nmaddr){ qlock(nif); t = 0; diff --git a/port/netif.h b/port/netif.h index 2312a4ebae0fd00fcb9ddc22d1ac283119db1977..7c14ff3d418df3fab45411cab5273cad849784a5 100644 --- a/port/netif.h +++ b/port/netif.h @@ -39,6 +39,7 @@ struct Netfile int type; /* multiplexor type */ int prom; /* promiscuous mode */ + int scan; /* base station scanning interval */ int bridge; /* bridge mode */ int headersonly; /* headers only - no data */ uchar maddr[8]; /* bitmask of multicast addresses requested */ @@ -79,6 +80,7 @@ struct Netif int nmaddr; /* number of known multicast addresses */ Netaddr *mhash[Nmhash]; /* hash table of multicast addresses */ int prom; /* number of promiscuous opens */ + int scan; /* number of base station scanners */ int all; /* number of -1 multiplexors */ /* statistics */ @@ -96,6 +98,7 @@ struct Netif void *arg; void (*promiscuous)(void*, int); void (*multicast)(void*, uchar*, int); + void (*scanbs)(void*, uint); /* scan for base stations */ }; void netifinit(Netif*, char*, int, ulong);