~kris/9p

9hist

cf9231140406536603da3b1517c38e4e159e8921 — David du Colombier 23 years ago 05bc930
Plan 9 from Bell Labs 2003-01-18
5 files changed, 114 insertions(+), 55 deletions(-)

M pc/uarti8250.c
M pc/wavelan.c
M pc/wavelan.h
M port/netif.c
M port/netif.h
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 = &ether->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);