if_iwireg.h revision 156546
1/*	$FreeBSD: head/sys/dev/iwi/if_iwireg.h 156546 2006-03-10 19:59:09Z damien $	*/
2
3/*-
4 * Copyright (c) 2004-2006
5 *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice unmodified, this list of conditions, and the following
12 *    disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#define IWI_CMD_RING_COUNT	16
31#define IWI_TX_RING_COUNT	64
32#define IWI_RX_RING_COUNT	32
33
34#define IWI_TX_DESC_SIZE	(sizeof (struct iwi_tx_desc))
35#define IWI_CMD_DESC_SIZE	(sizeof (struct iwi_cmd_desc))
36
37#define IWI_CSR_INTR		0x0008
38#define IWI_CSR_INTR_MASK	0x000c
39#define IWI_CSR_INDIRECT_ADDR	0x0010
40#define IWI_CSR_INDIRECT_DATA	0x0014
41#define IWI_CSR_AUTOINC_ADDR	0x0018
42#define IWI_CSR_AUTOINC_DATA	0x001c
43#define IWI_CSR_RST		0x0020
44#define IWI_CSR_CTL		0x0024
45#define IWI_CSR_IO		0x0030
46#define IWI_CSR_CMD_BASE	0x0200
47#define IWI_CSR_CMD_SIZE	0x0204
48#define IWI_CSR_TX1_BASE	0x0208
49#define IWI_CSR_TX1_SIZE	0x020c
50#define IWI_CSR_TX2_BASE	0x0210
51#define IWI_CSR_TX2_SIZE	0x0214
52#define IWI_CSR_TX3_BASE	0x0218
53#define IWI_CSR_TX3_SIZE	0x021c
54#define IWI_CSR_TX4_BASE	0x0220
55#define IWI_CSR_TX4_SIZE	0x0224
56#define IWI_CSR_CMD_RIDX	0x0280
57#define IWI_CSR_TX1_RIDX	0x0284
58#define IWI_CSR_TX2_RIDX	0x0288
59#define IWI_CSR_TX3_RIDX	0x028c
60#define IWI_CSR_TX4_RIDX	0x0290
61#define IWI_CSR_RX_RIDX		0x02a0
62#define IWI_CSR_RX_BASE		0x0500
63#define IWI_CSR_TABLE0_SIZE	0x0700
64#define IWI_CSR_TABLE0_BASE	0x0704
65#define IWI_CSR_NODE_BASE	0x0c0c
66#define IWI_CSR_CMD_WIDX	0x0f80
67#define IWI_CSR_TX1_WIDX	0x0f84
68#define IWI_CSR_TX2_WIDX	0x0f88
69#define IWI_CSR_TX3_WIDX	0x0f8c
70#define IWI_CSR_TX4_WIDX	0x0f90
71#define IWI_CSR_RX_WIDX		0x0fa0
72#define IWI_CSR_READ_INT	0x0ff4
73
74/* aliases */
75#define IWI_CSR_CURRENT_TX_RATE	IWI_CSR_TABLE0_BASE
76
77/* flags for IWI_CSR_INTR */
78#define IWI_INTR_RX_DONE	0x00000002
79#define IWI_INTR_CMD_DONE	0x00000800
80#define IWI_INTR_TX1_DONE	0x00001000
81#define IWI_INTR_TX2_DONE	0x00002000
82#define IWI_INTR_TX3_DONE	0x00004000
83#define IWI_INTR_TX4_DONE	0x00008000
84#define IWI_INTR_FW_INITED	0x01000000
85#define IWI_INTR_RADIO_OFF	0x04000000
86#define IWI_INTR_FATAL_ERROR	0x40000000
87#define IWI_INTR_PARITY_ERROR	0x80000000
88
89#define IWI_INTR_MASK							\
90	(IWI_INTR_RX_DONE | IWI_INTR_CMD_DONE |	IWI_INTR_TX1_DONE | 	\
91	 IWI_INTR_TX2_DONE | IWI_INTR_TX3_DONE | IWI_INTR_TX4_DONE |	\
92	 IWI_INTR_FW_INITED | IWI_INTR_RADIO_OFF |			\
93	 IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)
94
95/* flags for IWI_CSR_RST */
96#define IWI_RST_PRINCETON_RESET	0x00000001
97#define IWI_RST_SOFT_RESET	0x00000080
98#define IWI_RST_MASTER_DISABLED	0x00000100
99#define IWI_RST_STOP_MASTER	0x00000200
100
101/* flags for IWI_CSR_CTL */
102#define IWI_CTL_CLOCK_READY	0x00000001
103#define IWI_CTL_ALLOW_STANDBY	0x00000002
104#define IWI_CTL_INIT		0x00000004
105
106/* flags for IWI_CSR_IO */
107#define IWI_IO_RADIO_ENABLED	0x00010000
108
109/* flags for IWI_CSR_READ_INT */
110#define IWI_READ_INT_INIT_HOST	0x20000000
111
112/* constants for command blocks */
113#define IWI_CB_DEFAULT_CTL	0x8cea0000
114#define IWI_CB_MAXDATALEN	8191
115
116/* supported rates */
117#define IWI_RATE_DS1	10
118#define IWI_RATE_DS2	20
119#define IWI_RATE_DS5	55
120#define IWI_RATE_DS11	110
121#define IWI_RATE_OFDM6	13
122#define IWI_RATE_OFDM9	15
123#define IWI_RATE_OFDM12	5
124#define IWI_RATE_OFDM18	7
125#define IWI_RATE_OFDM24	9
126#define IWI_RATE_OFDM36	11
127#define IWI_RATE_OFDM48	1
128#define IWI_RATE_OFDM54	3
129
130/* firmware binary image header */
131struct iwi_firmware_hdr {
132	uint32_t	version;
133	uint32_t	bootsz;
134	uint32_t	ucodesz;
135	uint32_t	fwsz;
136} __packed;
137
138struct iwi_hdr {
139	uint8_t	type;
140#define IWI_HDR_TYPE_DATA	0
141#define IWI_HDR_TYPE_COMMAND	1
142#define IWI_HDR_TYPE_NOTIF	3
143#define IWI_HDR_TYPE_FRAME	9
144
145	uint8_t	seq;
146	uint8_t	flags;
147#define IWI_HDR_FLAG_IRQ	0x04
148
149	uint8_t	reserved;
150} __packed;
151
152struct iwi_notif {
153	uint32_t	reserved[2];
154	uint8_t		type;
155#define IWI_NOTIF_TYPE_ASSOCIATION	10
156#define IWI_NOTIF_TYPE_AUTHENTICATION	11
157#define IWI_NOTIF_TYPE_SCAN_CHANNEL	12
158#define IWI_NOTIF_TYPE_SCAN_COMPLETE	13
159#define IWI_NOTIF_TYPE_BEACON		17
160#define IWI_NOTIF_TYPE_CALIBRATION	20
161#define IWI_NOTIF_TYPE_NOISE		25
162
163	uint8_t		flags;
164	uint16_t	len;
165} __packed;
166
167/* structure for notification IWI_NOTIF_TYPE_AUTHENTICATION */
168struct iwi_notif_authentication {
169	uint8_t	state;
170#define IWI_DEAUTHENTICATED	0
171#define IWI_AUTHENTICATED	9
172} __packed;
173
174/* structure for notification IWI_NOTIF_TYPE_ASSOCIATION */
175struct iwi_notif_association {
176	uint8_t			state;
177#define IWI_DEASSOCIATED	0
178#define IWI_ASSOCIATED		12
179
180	struct ieee80211_frame	frame;
181	uint16_t		capinfo;
182	uint16_t		status;
183	uint16_t		associd;
184} __packed;
185
186/* structure for notification IWI_NOTIF_TYPE_SCAN_CHANNEL */
187struct iwi_notif_scan_channel {
188	uint8_t	nchan;
189	uint8_t	reserved[47];
190} __packed;
191
192/* structure for notification IWI_NOTIF_TYPE_SCAN_COMPLETE */
193struct iwi_notif_scan_complete {
194	uint8_t	type;
195	uint8_t	nchan;
196	uint8_t	status;
197	uint8_t	reserved;
198} __packed;
199
200/* received frame header */
201struct iwi_frame {
202	uint32_t	reserved1[2];
203	uint8_t		chan;
204	uint8_t		status;
205	uint8_t		rate;
206	uint8_t		rssi;
207	uint8_t		agc;
208	uint8_t		rssi_dbm;
209	uint16_t	signal;
210	uint16_t	noise;
211	uint8_t		antenna;
212	uint8_t		control;
213	uint8_t		reserved2[2];
214	uint16_t	len;
215} __packed;
216
217/* header for transmission */
218struct iwi_tx_desc {
219	struct iwi_hdr	hdr;
220	uint32_t	reserved1;
221	uint8_t		station;
222	uint8_t		reserved2[3];
223	uint8_t		cmd;
224#define IWI_DATA_CMD_TX	0x0b
225
226	uint8_t		seq;
227	uint16_t	len;
228	uint8_t		priority;
229	uint8_t		flags;
230#define IWI_DATA_FLAG_SHPREAMBLE	0x04
231#define IWI_DATA_FLAG_NO_WEP		0x20
232#define IWI_DATA_FLAG_NEED_ACK		0x80
233
234	uint8_t		xflags;
235#define IWI_DATA_XFLAG_QOS	0x10
236
237	uint8_t		weptxkey;
238	uint8_t		wepkey[IEEE80211_KEYBUF_SIZE];
239	uint8_t		rate;
240	uint8_t		antenna;
241	uint8_t		reserved3[10];
242	struct ieee80211_qosframe_addr4	wh;
243	uint32_t	iv;
244	uint32_t	eiv;
245	uint32_t	nseg;
246#define IWI_MAX_NSEG	6
247
248	uint32_t	seg_addr[IWI_MAX_NSEG];
249	uint16_t	seg_len[IWI_MAX_NSEG];
250} __packed;
251
252/* command */
253struct iwi_cmd_desc {
254	struct iwi_hdr	hdr;
255	uint8_t		type;
256#define IWI_CMD_ENABLE				2
257#define IWI_CMD_SET_CONFIG			6
258#define IWI_CMD_SET_ESSID			8
259#define IWI_CMD_SET_MAC_ADDRESS			11
260#define IWI_CMD_SET_RTS_THRESHOLD		15
261#define IWI_CMD_SET_FRAG_THRESHOLD		16
262#define IWI_CMD_SET_POWER_MODE			17
263#define IWI_CMD_SET_WEP_KEY			18
264#define IWI_CMD_ASSOCIATE			21
265#define IWI_CMD_SET_RATES			22
266#define IWI_CMD_ABORT_SCAN			23
267#define IWI_CMD_SET_WME_PARAMS			25
268#define IWI_CMD_SCAN				26
269#define IWI_CMD_SET_OPTIE			31
270#define IWI_CMD_DISABLE				33
271#define IWI_CMD_SET_IV				34
272#define IWI_CMD_SET_TX_POWER			35
273#define IWI_CMD_SET_SENSITIVITY			42
274#define IWI_CMD_SET_WMEIE			84
275
276	uint8_t		len;
277	uint16_t	reserved;
278	uint8_t		data[120];
279} __packed;
280
281/* node information (IBSS) */
282struct iwi_ibssnode {
283	uint8_t	bssid[IEEE80211_ADDR_LEN];
284	uint8_t	reserved[2];
285} __packed;
286
287/* constants for 'mode' fields */
288#define IWI_MODE_11A	0
289#define IWI_MODE_11B	1
290#define IWI_MODE_11G	2
291
292/* possible values for command IWI_CMD_SET_POWER_MODE */
293#define IWI_POWER_MODE_CAM	0
294
295/* structure for command IWI_CMD_SET_RATES */
296struct iwi_rateset {
297	uint8_t	mode;
298	uint8_t	nrates;
299	uint8_t	type;
300#define IWI_RATESET_TYPE_NEGOTIATED	0
301#define IWI_RATESET_TYPE_SUPPORTED	1
302
303	uint8_t	reserved;
304	uint8_t	rates[12];
305} __packed;
306
307/* structure for command IWI_CMD_SET_TX_POWER */
308struct iwi_txpower {
309	uint8_t	nchan;
310	uint8_t	mode;
311	struct {
312		uint8_t	chan;
313		uint8_t	power;
314#define IWI_TXPOWER_MAX		20
315#define IWI_TXPOWER_RATIO	(IEEE80211_TXPOWER_MAX / IWI_TXPOWER_MAX)
316	} __packed chan[37];
317} __packed;
318
319/* structure for command IWI_CMD_ASSOCIATE */
320struct iwi_associate {
321	uint8_t		chan;
322	uint8_t		auth;
323#define IWI_AUTH_OPEN	0
324#define IWI_AUTH_SHARED	1
325#define IWI_AUTH_NONE	3
326
327	uint8_t		type;
328	uint8_t		reserved1;
329	uint16_t	policy;
330#define IWI_POLICY_WME	1
331#define IWI_POLICY_WPA	2
332
333	uint8_t		plen;
334	uint8_t		mode;
335	uint8_t		bssid[IEEE80211_ADDR_LEN];
336	uint8_t		tstamp[8];
337	uint16_t	capinfo;
338	uint16_t	lintval;
339	uint16_t	intval;
340	uint8_t		dst[IEEE80211_ADDR_LEN];
341	uint32_t	reserved3;
342	uint16_t	reserved4;
343} __packed;
344
345/* structure for command IWI_CMD_SCAN */
346struct iwi_scan {
347	uint32_t	index;
348	uint8_t		channels[54];
349#define IWI_CHAN_5GHZ	(0 << 6)
350#define IWI_CHAN_2GHZ	(1 << 6)
351
352	uint8_t		type[27];
353#define IWI_SCAN_TYPE_PASSIVE	0x11
354#define IWI_SCAN_TYPE_DIRECTED	0x22
355#define IWI_SCAN_TYPE_BROADCAST	0x33
356#define IWI_SCAN_TYPE_BDIRECTED	0x44
357
358	uint8_t		reserved1;
359	uint16_t	reserved2;
360	uint16_t	passive;	/* dwell time */
361	uint16_t	directed;	/* dwell time */
362	uint16_t	broadcast;	/* dwell time */
363	uint16_t	bdirected;	/* dwell time */
364} __packed;
365
366/* structure for command IWI_CMD_SET_CONFIG */
367struct iwi_configuration {
368	uint8_t	bluetooth_coexistence;
369	uint8_t	reserved1;
370	uint8_t	answer_pbreq;
371	uint8_t	allow_invalid_frames;
372	uint8_t	multicast_enabled;
373	uint8_t	drop_unicast_unencrypted;
374	uint8_t	disable_unicast_decryption;
375	uint8_t	drop_multicast_unencrypted;
376	uint8_t	disable_multicast_decryption;
377	uint8_t	antenna;
378	uint8_t	reserved2;
379	uint8_t	use_protection;
380	uint8_t	protection_ctsonly;
381	uint8_t	enable_multicast_filtering;
382	uint8_t	bluetooth_threshold;
383	uint8_t	reserved4;
384	uint8_t	allow_beacon_and_probe_resp;
385	uint8_t	allow_mgt;
386	uint8_t	noise_reported;
387	uint8_t	reserved5;
388} __packed;
389
390/* structure for command IWI_CMD_SET_WEP_KEY */
391struct iwi_wep_key {
392	uint8_t	cmd;
393#define IWI_WEP_KEY_CMD_SETKEY	0x08
394
395	uint8_t	seq;
396	uint8_t	idx;
397	uint8_t	len;
398	uint8_t	key[IEEE80211_KEYBUF_SIZE];
399} __packed;
400
401/* structure for command IWI_CMD_SET_WME_PARAMS */
402struct iwi_wme_params {
403	uint16_t	cwmin[WME_NUM_AC];
404	uint16_t	cwmax[WME_NUM_AC];
405	uint8_t		aifsn[WME_NUM_AC];
406	uint8_t		acm[WME_NUM_AC];
407	uint16_t	burst[WME_NUM_AC];
408} __packed;
409
410#define IWI_MEM_EVENT_CTL	0x00300004
411#define IWI_MEM_EEPROM_CTL	0x00300040
412
413/* possible flags for register IWI_MEM_EVENT */
414#define IWI_LED_ASSOC	(1 << 5)
415#define IWI_LED_MASK	0xd9fffffb
416
417#define IWI_EEPROM_MAC	0x21
418
419#define IWI_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
420
421#define IWI_EEPROM_C	(1 << 0)	/* Serial Clock */
422#define IWI_EEPROM_S	(1 << 1)	/* Chip Select */
423#define IWI_EEPROM_D	(1 << 2)	/* Serial data input */
424#define IWI_EEPROM_Q	(1 << 4)	/* Serial data output */
425
426#define IWI_EEPROM_SHIFT_D    2
427#define IWI_EEPROM_SHIFT_Q    4
428
429/*
430 * control and status registers access macros
431 */
432#define CSR_READ_1(sc, reg)						\
433	bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
434
435#define CSR_READ_2(sc, reg)						\
436	bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))
437
438#define CSR_READ_4(sc, reg)						\
439	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
440
441#define CSR_READ_REGION_4(sc, offset, datap, count)			\
442	bus_space_read_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
443	    (datap), (count))
444
445#define CSR_WRITE_1(sc, reg, val)					\
446	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
447
448#define CSR_WRITE_2(sc, reg, val)					\
449	bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
450
451#define CSR_WRITE_4(sc, reg, val)					\
452	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
453
454#define CSR_WRITE_REGION_1(sc, offset, datap, count)			\
455	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
456	    (datap), (count))
457
458/*
459 * indirect memory space access macros
460 */
461#define MEM_READ_1(sc, addr)						\
462	(CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr)),		\
463	 CSR_READ_1((sc), IWI_CSR_INDIRECT_DATA))
464
465#define MEM_READ_4(sc, addr)						\
466	(CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr)),		\
467	 CSR_READ_4((sc), IWI_CSR_INDIRECT_DATA))
468
469#define MEM_WRITE_1(sc, addr, val) do {					\
470	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
471	CSR_WRITE_1((sc), IWI_CSR_INDIRECT_DATA, (val));		\
472} while (/* CONSTCOND */0)
473
474#define MEM_WRITE_2(sc, addr, val) do {					\
475	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
476	CSR_WRITE_2((sc), IWI_CSR_INDIRECT_DATA, (val));		\
477} while (/* CONSTCOND */0)
478
479#define MEM_WRITE_4(sc, addr, val) do {					\
480	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
481	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_DATA, (val));		\
482} while (/* CONSTCOND */0)
483
484#define MEM_WRITE_MULTI_1(sc, addr, buf, len) do {			\
485	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
486	CSR_WRITE_MULTI_1((sc), IWI_CSR_INDIRECT_DATA, (buf), (len));	\
487} while (/* CONSTCOND */0)
488
489/*
490 * EEPROM access macro
491 */
492#define IWI_EEPROM_CTL(sc, val) do {					\
493	MEM_WRITE_4((sc), IWI_MEM_EEPROM_CTL, (val));			\
494	DELAY(IWI_EEPROM_DELAY);					\
495} while (/* CONSTCOND */0)
496