M pc/uarti8250.c => pc/uarti8250.c +25 -29
@@ 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:
M pc/wavelan.c => pc/wavelan.c +63 -23
@@ 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",
M pc/wavelan.h => pc/wavelan.h +4 -3
@@ 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[];
M port/netif.c => port/netif.c +19 -0
@@ 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;
M port/netif.h => port/netif.h +3 -0
@@ 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);