summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/wavelan.h
blob: 7f76149e0253499b357e40aca9e05da6a7b644ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#define DEBUG	if(1){}else print

#define SEEKEYS 0

// Lucent's Length-Type-Value records to talk to the wavelan.
// most operational parameters are read/set using this.
enum
{
	WTyp_Stats	= 0xf100,
	WTyp_Scan	= 0xf101,
	WTyp_Link	= 0xf200,
	WTyp_Ptype	= 0xfc00,
	WTyp_Mac	= 0xfc01,
	WTyp_WantName	= 0xfc02,
	WTyp_Chan	= 0xfc03,
	WTyp_NetName	= 0xfc04,
	WTyp_ApDens	= 0xfc06,
	WTyp_MaxLen	= 0xfc07,
	WTyp_PM		= 0xfc09,
	WTyp_PMWait	= 0xfc0c,
	WTyp_NodeName	= 0xfc0e,
	WTyp_Crypt	= 0xfc20,
	WTyp_XClear	= 0xfc22,
 	WTyp_CreateIBSS	= 0xfc81,
	WTyp_RtsThres	= 0xfc83,
	WTyp_TxRate	= 0xfc84,
		WTx1Mbps	= 0x0,
		WTx2Mbps	= 0x1,
		WTxAuto		= 0x3,
	WTyp_Prom	= 0xfc85,
	WTyp_Keys	= 0xfcb0,
	WTyp_TxKey	= 0xfcb1,
	WTyp_StationID	= 0xfd20,
	WTyp_CurName	= 0xfd41,
	WTyp_BaseID	= 0xfd42,	// ID of the currently connected-to base station
	WTyp_CurTxRate	= 0xfd44,	// Current TX rate
	WTyp_HasCrypt	= 0xfd4f,
	WTyp_Tick	= 0xfce0,
};

// Controller
enum
{
	WDfltIRQ	= 3,		// default irq
	WDfltIOB	= 0x180,	// default IO base

	WIOLen		= 0x40,		// Hermes IO length

	WTmOut		= 65536,	// Cmd time out

	WPTypeManaged	= 1,
	WPTypeWDS	= 2,
	WPTypeAdHoc	= 3,
	WDfltPType	= WPTypeManaged,

	WDfltApDens	= 1,
	WDfltRtsThres	= 2347,		// == disabled
	WDfltTxRate	= WTxAuto,	// 2Mbps

	WMaxLen		= 2304,
	WNameLen	= 32,

	WNKeys		= 4,
	WKeyLen		= 14,
	WMinKeyLen	= 5,
	WMaxKeyLen	= 13,

	// Wavelan hermes registers
	WR_Cmd		= 0x00,
		WCmdIni		= 0x0000,
		WCmdEna		= 0x0001,
		WCmdDis		= 0x0002,
		WCmdTx		= 0x000b,
		WCmdMalloc	= 0x000a,
		WCmdEnquire	= 0x0011,
		WCmdMsk		= 0x003f,
		WCmdAccRd	= 0x0021,
		WCmdReclaim	= 0x0100,
		WCmdAccWr	= 0x0121,
		WCmdBusy	= 0x8000,
	WR_Parm0	= 0x02,
	WR_Parm1	= 0x04,
	WR_Parm2	= 0x06,
	WR_Sts		= 0x08,
	WR_InfoId	= 0x10,
	WR_Sel0		= 0x18,
	WR_Sel1		= 0x1a,
	WR_Off0		= 0x1c,
	WR_Off1		= 0x1e,
		WBusyOff	= 0x8000,
		WErrOff		= 0x4000,
		WResSts		= 0x7f00,
	WR_RXId		= 0x20,
	WR_Alloc	= 0x22,
	WR_EvSts	= 0x30,
	WR_IntEna	= 0x32,
		WCmdEv		= 0x0010,
		WRXEv		= 0x0001,
		WTXEv		= 0x0002,
		WTxErrEv	= 0x0004,
		WAllocEv	= 0x0008,
		WInfoEv		= 0x0080,
		WIDropEv	= 0x2000,
		WTickEv		= 0x8000,
		WEvs		= WRXEv|WTXEv|WAllocEv|WInfoEv|WIDropEv,

	WR_EvAck	= 0x34,
	WR_Data0	= 0x36,
	WR_Data1	= 0x38,

	WR_PciCor	= 0x26,
	WR_PciHcr	= 0x2E,

	// Frame stuff

	WF_Err		= 0x0003,
	WF_1042		= 0x2000,
	WF_Tunnel	= 0x4000,
	WF_WMP		= 0x6000,

	WF_Data		= 0x0008,

	WSnapK1		= 0xaa,
	WSnapK2		= 0x00,
	WSnapCtlr	= 0x03,
	WSnap0		= (WSnapK1|(WSnapK1<<8)),
	WSnap1		= (WSnapK2|(WSnapCtlr<<8)),
	WSnapHdrLen	= 6,

	WF_802_11_Off	= 0x44,
	WF_802_3_Off	= 0x2e,

};

typedef struct Ctlr	Ctlr;
typedef struct Wltv	Wltv;
typedef struct WFrame	WFrame;
typedef struct Stats	Stats;
typedef struct WStats	WStats;
typedef struct WScan	WScan;
typedef struct WKey	WKey;

struct WStats
{
	ulong	ntxuframes;		// unicast frames
	ulong	ntxmframes;		// multicast frames
	ulong	ntxfrags;		// fragments
	ulong	ntxubytes;		// unicast bytes
	ulong	ntxmbytes;		// multicast bytes
	ulong	ntxdeferred;		// deferred transmits
	ulong	ntxsretries;		// single retries
	ulong	ntxmultiretries;	// multiple retries
	ulong	ntxretrylimit;
	ulong	ntxdiscards;
	ulong	nrxuframes;		// unicast frames
	ulong	nrxmframes;		// multicast frames
	ulong	nrxfrags;		// fragments
	ulong	nrxubytes;		// unicast bytes
	ulong	nrxmbytes;		// multicast bytes
	ulong	nrxfcserr;
	ulong	nrxdropnobuf;
	ulong	nrxdropnosa;
	ulong	nrxcantdecrypt;
	ulong	nrxmsgfrag;
	ulong	nrxmsgbadfrag;
	ulong	end;
};

struct WScan
{
	ushort	chan;			/* dss channel */
	ushort	noise;			/* average noise in the air */
	ushort	signal;			/* signal strength */
	uchar	bssid[Eaddrlen];	/* MAC address of the ap */
	ushort	interval;		/* beacon transmit interval */
	ushort	capinfo;		/* capability bits (0-ess, 1-ibss, 4-privacy [wep]) */
	ushort	ssid_len;		/* ssid length */
	char	ssid[WNameLen];		/* ssid (ap name) */
};

struct WFrame
{
	ushort	sts;
	ushort	rsvd0;
	ushort	rsvd1;
	ushort	qinfo;
	ushort	rsvd2;
	ushort	rsvd3;
	ushort	txctl;
	ushort	framectl;
	ushort	id;
	uchar	addr1[Eaddrlen];
	uchar	addr2[Eaddrlen];
	uchar	addr3[Eaddrlen];
	ushort	seqctl;
	uchar	addr4[Eaddrlen];
	ushort	dlen;
	uchar	dstaddr[Eaddrlen];
	uchar	srcaddr[Eaddrlen];
	ushort	len;
	ushort	dat[3];
	ushort	type;
};

struct WKey
{
	ushort	len;
	char	dat[WKeyLen];
};

struct Wltv
{
	ushort	len;
	ushort	type;
	union
	{
		struct {
			ushort	val;
			ushort	pad;
		};
		struct {
			uchar	addr[8];
		};
		struct {
			ushort	slen;
			char	s[WNameLen];
		};
		struct {
			char	name[WNameLen];
		};
		struct {
			WKey	keys[WNKeys];
		};
	};
};

// What the driver thinks. Not what the card thinks.
struct Stats
{
	ulong	nints;
	ulong	ndoubleint;
	ulong	nrx;
	ulong	ntx;
	ulong	ntxrq;
	ulong	nrxerr;
	ulong	ntxerr;
	ulong	nalloc;			// allocation (reclaim) events
	ulong	ninfo;
	ulong	nidrop;
	ulong	nwatchdogs;		// transmit time outs, actually
	int	ticks;
	int	tickintr;
	int	signal;
	int	noise;
};

enum {
	Attached = 0x01,
	Power = 0x02,
};

struct Ctlr
{
	Lock;

	int	state;	// Attached | Power
	int	slot;
	int	iob;
 	int	createibss;
	int	ptype;
	int	apdensity;
	int	rtsthres;
	int	txbusy;
	int	txrate;
	int	txdid;
	int	txmid;
	int	txtmout;
	int	maxlen;
	int	chan;
	int	pmena;
	int	pmwait;

	Proc	*timerproc;
	int	scanticks;

	char	netname[WNameLen];
	char	wantname[WNameLen];
	char	nodename[WNameLen];
	WFrame	txf;
	uchar	txbuf[1536];

	int	hascrypt;		// card has encryption
	int	crypt;			// encryption off/on
	int	txkey;			// transmit key
	Wltv	keys;			// default keys
	int	xclear;			// exclude clear packets off/on

	int	ctlrno;

	ushort	*mmb;
	/* for PCI-based devices */
	Ctlr	*next;
	int	active;
	Pcidev	*pcidev;

	Stats;
	WStats;
};

extern char* wavenames[];

void	csr_outs(Ctlr*, int, ushort);
ushort	csr_ins(Ctlr*, int);
void	w_intdis(Ctlr*);
int	w_cmd(Ctlr *, ushort, ushort);
void	ltv_outs(Ctlr*, int, ushort);
int	ltv_ins(Ctlr*, int);
int	w_option(Ctlr*, char*, long);
int	w_inltv(Ctlr*, Wltv*);
void	w_attach(Ether*);
void	w_interrupt(Ureg*,void*);
void	w_transmit(Ether*);
long	w_ifstat(Ether*, void*, long, ulong);
long	w_ctl(Ether*, void*, long);
void	w_promiscuous(void*, int);
void	w_multicast(void*, uchar*, int);
int	wavelanreset(Ether*, Ctlr*);