if_ipwreg.h revision 156599
1145247Sdamien/*      $FreeBSD: head/sys/dev/ipw/if_ipwreg.h 156599 2006-03-12 19:01:00Z damien $	*/
2145247Sdamien
3145247Sdamien/*-
4156599Sdamien * Copyright (c) 2004-2006
5145247Sdamien *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
6145247Sdamien *
7145247Sdamien * Redistribution and use in source and binary forms, with or without
8145247Sdamien * modification, are permitted provided that the following conditions
9145247Sdamien * are met:
10145247Sdamien * 1. Redistributions of source code must retain the above copyright
11145247Sdamien *    notice unmodified, this list of conditions, and the following
12145247Sdamien *    disclaimer.
13145247Sdamien * 2. Redistributions in binary form must reproduce the above copyright
14145247Sdamien *    notice, this list of conditions and the following disclaimer in the
15145247Sdamien *    documentation and/or other materials provided with the distribution.
16145247Sdamien *
17145247Sdamien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18145247Sdamien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19145247Sdamien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20145247Sdamien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21145247Sdamien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22145247Sdamien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23145247Sdamien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24145247Sdamien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25145247Sdamien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26145247Sdamien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27145247Sdamien * SUCH DAMAGE.
28145247Sdamien */
29145247Sdamien
30145247Sdamien#define IPW_NTBD	128
31145247Sdamien#define IPW_TBD_SZ	(IPW_NTBD * sizeof (struct ipw_bd))
32145247Sdamien#define IPW_NDATA	(IPW_NTBD / 2)
33145247Sdamien#define IPW_NRBD	128
34145247Sdamien#define IPW_RBD_SZ	(IPW_NRBD * sizeof (struct ipw_bd))
35145247Sdamien#define IPW_STATUS_SZ	(IPW_NRBD * sizeof (struct ipw_status))
36145247Sdamien
37145247Sdamien#define IPW_CSR_INTR		0x0008
38145247Sdamien#define IPW_CSR_INTR_MASK	0x000c
39145247Sdamien#define IPW_CSR_INDIRECT_ADDR	0x0010
40145247Sdamien#define IPW_CSR_INDIRECT_DATA	0x0014
41145247Sdamien#define IPW_CSR_AUTOINC_ADDR	0x0018
42145247Sdamien#define IPW_CSR_AUTOINC_DATA	0x001c
43145247Sdamien#define IPW_CSR_RST		0x0020
44145247Sdamien#define IPW_CSR_CTL		0x0024
45145247Sdamien#define IPW_CSR_IO		0x0030
46145247Sdamien#define IPW_CSR_TX_BASE		0x0200
47145247Sdamien#define IPW_CSR_TX_SIZE		0x0204
48145247Sdamien#define IPW_CSR_RX_BASE		0x0240
49145247Sdamien#define IPW_CSR_STATUS_BASE	0x0244
50145247Sdamien#define IPW_CSR_RX_SIZE		0x0248
51145247Sdamien#define IPW_CSR_TX_READ		0x0280
52145247Sdamien#define IPW_CSR_RX_READ		0x02a0
53145247Sdamien#define IPW_CSR_TABLE1_BASE	0x0380
54145247Sdamien#define IPW_CSR_TABLE2_BASE	0x0384
55145247Sdamien#define IPW_CSR_TX_WRITE	0x0f80
56145247Sdamien#define IPW_CSR_RX_WRITE	0x0fa0
57145247Sdamien
58145247Sdamien/* possible flags for register IPW_CSR_INTR */
59145247Sdamien#define IPW_INTR_TX_TRANSFER	0x00000001
60145247Sdamien#define IPW_INTR_RX_TRANSFER	0x00000002
61145247Sdamien#define IPW_INTR_STATUS_CHANGE	0x00000010
62145247Sdamien#define IPW_INTR_COMMAND_DONE	0x00010000
63145247Sdamien#define IPW_INTR_FW_INIT_DONE	0x01000000
64145247Sdamien#define IPW_INTR_FATAL_ERROR	0x40000000
65145247Sdamien#define IPW_INTR_PARITY_ERROR	0x80000000
66145247Sdamien
67145247Sdamien#define IPW_INTR_MASK							\
68145247Sdamien	(IPW_INTR_TX_TRANSFER | IPW_INTR_RX_TRANSFER |			\
69145247Sdamien	 IPW_INTR_STATUS_CHANGE | IPW_INTR_COMMAND_DONE |		\
70145247Sdamien	 IPW_INTR_FW_INIT_DONE | IPW_INTR_FATAL_ERROR |			\
71145247Sdamien	 IPW_INTR_PARITY_ERROR)
72145247Sdamien
73145247Sdamien/* possible flags for register IPW_CSR_RST */
74145247Sdamien#define IPW_RST_PRINCETON_RESET	0x00000001
75145247Sdamien#define IPW_RST_SW_RESET	0x00000080
76145247Sdamien#define IPW_RST_MASTER_DISABLED	0x00000100
77145247Sdamien#define IPW_RST_STOP_MASTER	0x00000200
78145247Sdamien
79145247Sdamien/* possible flags for register IPW_CSR_CTL */
80145247Sdamien#define IPW_CTL_CLOCK_READY	0x00000001
81145247Sdamien#define IPW_CTL_ALLOW_STANDBY	0x00000002
82145247Sdamien#define IPW_CTL_INIT		0x00000004
83145247Sdamien
84145247Sdamien/* possible flags for register IPW_CSR_IO */
85145247Sdamien#define IPW_IO_GPIO1_ENABLE	0x00000008
86145247Sdamien#define IPW_IO_GPIO1_MASK	0x0000000c
87145247Sdamien#define IPW_IO_GPIO3_MASK	0x000000c0
88145247Sdamien#define IPW_IO_LED_OFF		0x00002000
89145247Sdamien#define IPW_IO_RADIO_DISABLED	0x00010000
90145247Sdamien
91145247Sdamien#define IPW_STATE_ASSOCIATED		0x0004
92145247Sdamien#define IPW_STATE_ASSOCIATION_LOST	0x0008
93145247Sdamien#define IPW_STATE_SCAN_COMPLETE		0x0020
94145247Sdamien#define IPW_STATE_RADIO_DISABLED	0x0100
95145247Sdamien#define IPW_STATE_DISABLED		0x0200
96145247Sdamien#define IPW_STATE_SCANNING		0x0800
97145247Sdamien
98145247Sdamien/* table1 offsets */
99145247Sdamien#define IPW_INFO_LOCK			480
100145247Sdamien#define IPW_INFO_APS_CNT		604
101145247Sdamien#define IPW_INFO_APS_BASE		608
102145247Sdamien#define IPW_INFO_CARD_DISABLED		628
103145247Sdamien#define IPW_INFO_CURRENT_CHANNEL	756
104145247Sdamien#define IPW_INFO_CURRENT_TX_RATE	768
105145247Sdamien
106145247Sdamien/* table2 offsets */
107145247Sdamien#define IPW_INFO_CURRENT_SSID	48
108145247Sdamien#define IPW_INFO_CURRENT_BSSID	112
109145247Sdamien
110145247Sdamien/* supported rates */
111145247Sdamien#define IPW_RATE_DS1	1
112145247Sdamien#define IPW_RATE_DS2	2
113145247Sdamien#define IPW_RATE_DS5	4
114145247Sdamien#define IPW_RATE_DS11	8
115145247Sdamien
116145247Sdamien/* firmware binary image header */
117145247Sdamienstruct ipw_firmware_hdr {
118156599Sdamien	uint32_t	version;
119156599Sdamien	uint32_t	mainsz;
120156599Sdamien	uint32_t	ucodesz;
121145247Sdamien} __packed;
122145247Sdamien
123145247Sdamien/* buffer descriptor */
124145247Sdamienstruct ipw_bd {
125156599Sdamien	uint32_t	physaddr;
126156599Sdamien	uint32_t	len;
127156599Sdamien	uint8_t		flags;
128145247Sdamien#define IPW_BD_FLAG_TX_FRAME_802_3		0x00
129145247Sdamien#define IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT	0x01
130145247Sdamien#define IPW_BD_FLAG_TX_FRAME_COMMAND		0x02
131145247Sdamien#define IPW_BD_FLAG_TX_FRAME_802_11		0x04
132145247Sdamien#define IPW_BD_FLAG_TX_LAST_FRAGMENT		0x08
133156599Sdamien	uint8_t		nfrag;	/* number of fragments */
134156599Sdamien	uint8_t		reserved[6];
135145247Sdamien} __packed;
136145247Sdamien
137145247Sdamien/* status */
138145247Sdamienstruct ipw_status {
139156599Sdamien	uint32_t	len;
140156599Sdamien	uint16_t	code;
141145247Sdamien#define IPW_STATUS_CODE_COMMAND		0
142145247Sdamien#define IPW_STATUS_CODE_NEWSTATE	1
143145247Sdamien#define IPW_STATUS_CODE_DATA_802_11	2
144145247Sdamien#define IPW_STATUS_CODE_DATA_802_3	3
145145247Sdamien#define IPW_STATUS_CODE_NOTIFICATION	4
146156599Sdamien	uint8_t		flags;
147145247Sdamien#define IPW_STATUS_FLAG_DECRYPTED	0x01
148145247Sdamien#define IPW_STATUS_FLAG_WEP_ENCRYPTED	0x02
149156599Sdamien	uint8_t		rssi;	/* received signal strength indicator */
150145247Sdamien} __packed;
151145247Sdamien
152145247Sdamien/* data header */
153145247Sdamienstruct ipw_hdr {
154156599Sdamien	uint32_t	type;
155145247Sdamien#define IPW_HDR_TYPE_SEND	33
156156599Sdamien	uint32_t	subtype;
157156599Sdamien	uint8_t		encrypted;
158156599Sdamien	uint8_t		encrypt;
159156599Sdamien	uint8_t		keyidx;
160156599Sdamien	uint8_t		keysz;
161156599Sdamien	uint8_t		key[IEEE80211_KEYBUF_SIZE];
162156599Sdamien	uint8_t		reserved[10];
163156599Sdamien	uint8_t		src_addr[IEEE80211_ADDR_LEN];
164156599Sdamien	uint8_t		dst_addr[IEEE80211_ADDR_LEN];
165156599Sdamien	uint16_t	fragmentsz;
166145247Sdamien} __packed;
167145247Sdamien
168145247Sdamien/* command */
169145247Sdamienstruct ipw_cmd {
170156599Sdamien	uint32_t	type;
171145247Sdamien#define IPW_CMD_ENABLE				2
172145247Sdamien#define IPW_CMD_SET_CONFIGURATION		6
173145247Sdamien#define IPW_CMD_SET_ESSID			8
174145247Sdamien#define IPW_CMD_SET_MANDATORY_BSSID		9
175145247Sdamien#define IPW_CMD_SET_MAC_ADDRESS			11
176145247Sdamien#define IPW_CMD_SET_MODE			12
177145247Sdamien#define IPW_CMD_SET_CHANNEL			14
178145247Sdamien#define IPW_CMD_SET_RTS_THRESHOLD		15
179145247Sdamien#define IPW_CMD_SET_FRAG_THRESHOLD		16
180145247Sdamien#define IPW_CMD_SET_POWER_MODE			17
181145247Sdamien#define IPW_CMD_SET_TX_RATES			18
182145247Sdamien#define IPW_CMD_SET_BASIC_TX_RATES		19
183145247Sdamien#define IPW_CMD_SET_WEP_KEY			20
184145247Sdamien#define IPW_CMD_SET_WEP_KEY_INDEX		25
185145247Sdamien#define IPW_CMD_SET_WEP_FLAGS			26
186145247Sdamien#define IPW_CMD_ADD_MULTICAST			27
187145247Sdamien#define IPW_CMD_SET_BEACON_INTERVAL		29
188145247Sdamien#define IPW_CMD_SET_TX_POWER_INDEX		36
189145247Sdamien#define IPW_CMD_BROADCAST_SCAN			43
190145247Sdamien#define IPW_CMD_DISABLE				44
191145247Sdamien#define IPW_CMD_SET_DESIRED_BSSID		45
192145247Sdamien#define IPW_CMD_SET_SCAN_OPTIONS		46
193145247Sdamien#define IPW_CMD_PREPARE_POWER_DOWN		58
194145247Sdamien#define IPW_CMD_DISABLE_PHY			61
195145247Sdamien#define IPW_CMD_SET_SECURITY_INFORMATION	67
196145247Sdamien#define IPW_CMD_SET_WPA_IE			69
197156599Sdamien	uint32_t	subtype;
198156599Sdamien	uint32_t	seq;
199156599Sdamien	uint32_t	len;
200156599Sdamien	uint8_t		data[400];
201156599Sdamien	uint32_t	status;
202156599Sdamien	uint8_t		reserved[68];
203145247Sdamien} __packed;
204145247Sdamien
205145247Sdamien/* possible values for command IPW_CMD_SET_POWER_MODE */
206145247Sdamien#define IPW_POWER_MODE_CAM	0
207145247Sdamien#define IPW_POWER_AUTOMATIC	6
208145247Sdamien
209145247Sdamien/* possible values for command IPW_CMD_SET_MODE */
210145247Sdamien#define IPW_MODE_BSS		0
211145247Sdamien#define IPW_MODE_IBSS		1
212145247Sdamien#define IPW_MODE_MONITOR	2
213145247Sdamien
214145247Sdamien/* possible flags for command IPW_CMD_SET_WEP_FLAGS */
215145247Sdamien#define IPW_WEPON	0x8
216145247Sdamien
217145247Sdamien/* structure for command IPW_CMD_SET_WEP_KEY */
218145247Sdamienstruct ipw_wep_key {
219156599Sdamien	uint8_t	idx;
220156599Sdamien	uint8_t	len;
221156599Sdamien	uint8_t	key[13];
222145247Sdamien} __packed;
223145247Sdamien
224145247Sdamien/* structure for command IPW_CMD_SET_SECURITY_INFORMATION */
225145247Sdamienstruct ipw_security {
226156599Sdamien	uint32_t	ciphers;
227145247Sdamien#define IPW_CIPHER_NONE		0x00000001
228145247Sdamien#define IPW_CIPHER_WEP40	0x00000002
229145247Sdamien#define IPW_CIPHER_TKIP		0x00000004
230145247Sdamien#define IPW_CIPHER_CCMP		0x00000010
231145247Sdamien#define IPW_CIPHER_WEP104	0x00000020
232145247Sdamien#define IPW_CIPHER_CKIP		0x00000040
233156599Sdamien	uint16_t	reserved1;
234156599Sdamien	uint8_t		authmode;
235145247Sdamien#define IPW_AUTH_OPEN	0
236145247Sdamien#define IPW_AUTH_SHARED	1
237156599Sdamien	uint16_t	reserved2;
238145247Sdamien} __packed;
239145247Sdamien
240145247Sdamien/* structure for command IPW_CMD_SET_SCAN_OPTIONS */
241145247Sdamienstruct ipw_scan_options {
242156599Sdamien	uint32_t	flags;
243145247Sdamien#define IPW_SCAN_DO_NOT_ASSOCIATE	0x00000001
244145247Sdamien#define IPW_SCAN_PASSIVE		0x00000008
245156599Sdamien	uint32_t	channels;
246145247Sdamien} __packed;
247145247Sdamien
248145247Sdamien/* structure for command IPW_CMD_SET_CONFIGURATION */
249145247Sdamienstruct ipw_configuration {
250156599Sdamien	uint32_t	flags;
251145247Sdamien#define IPW_CFG_PROMISCUOUS	0x00000004
252145247Sdamien#define IPW_CFG_PREAMBLE_AUTO	0x00000010
253145247Sdamien#define IPW_CFG_IBSS_AUTO_START	0x00000020
254145247Sdamien#define IPW_CFG_802_1x_ENABLE	0x00004000
255145247Sdamien#define IPW_CFG_BSS_MASK	0x00008000
256145247Sdamien#define IPW_CFG_IBSS_MASK	0x00010000
257156599Sdamien	uint32_t	bss_chan;
258156599Sdamien	uint32_t	ibss_chan;
259145247Sdamien} __packed;
260145247Sdamien
261145247Sdamien/* structure for command IPW_CMD_SET_WPA_IE */
262145247Sdamienstruct ipw_wpa_ie {
263156599Sdamien	uint16_t	mask;
264156599Sdamien	uint16_t	capinfo;
265156599Sdamien	uint16_t	lintval;
266156599Sdamien	uint8_t		bssid[IEEE80211_ADDR_LEN];
267156599Sdamien	uint32_t	len;
268145247Sdamien	struct ieee80211_ie_wpa	ie;
269145247Sdamien} __packed;
270145247Sdamien
271145247Sdamien/* element in AP table */
272145247Sdamienstruct ipw_node {
273156599Sdamien	uint32_t	reserved1[2];
274156599Sdamien	uint8_t		bssid[IEEE80211_ADDR_LEN];
275156599Sdamien	uint8_t		chan;
276156599Sdamien	uint8_t		rates;
277156599Sdamien	uint16_t	reserved2;
278156599Sdamien	uint16_t	capinfo;
279156599Sdamien	uint16_t	reserved3;
280156599Sdamien	uint16_t	intval;
281156599Sdamien	uint8_t		reserved4[28];
282156599Sdamien	uint8_t		essid[IEEE80211_NWID_LEN];
283156599Sdamien	uint16_t	reserved5;
284156599Sdamien	uint8_t		esslen;
285156599Sdamien	uint8_t		reserved6[7];
286156599Sdamien	uint8_t		rssi;
287145247Sdamien} __packed;
288145247Sdamien
289145247Sdamien/* EEPROM = Electrically Erasable Programmable Read-Only Memory */
290145247Sdamien
291145247Sdamien#define IPW_MEM_EEPROM_CTL	0x00300040
292145247Sdamien
293145247Sdamien#define IPW_EEPROM_RADIO	0x11
294145247Sdamien#define IPW_EEPROM_MAC		0x21
295145247Sdamien#define IPW_EEPROM_CHANNEL_LIST	0x37
296145247Sdamien
297145247Sdamien#define IPW_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
298145247Sdamien
299145247Sdamien#define IPW_EEPROM_C	(1 << 0)	/* Serial Clock */
300145247Sdamien#define IPW_EEPROM_S	(1 << 1)	/* Chip Select */
301145247Sdamien#define IPW_EEPROM_D	(1 << 2)	/* Serial data input */
302145247Sdamien#define IPW_EEPROM_Q	(1 << 4)	/* Serial data output */
303145247Sdamien
304145247Sdamien#define IPW_EEPROM_SHIFT_D	2
305145247Sdamien#define IPW_EEPROM_SHIFT_Q	4
306145247Sdamien
307145247Sdamien/*
308145247Sdamien * control and status registers access macros
309145247Sdamien */
310145247Sdamien#define CSR_READ_1(sc, reg)						\
311145247Sdamien	bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
312145247Sdamien
313145247Sdamien#define CSR_READ_2(sc, reg)						\
314145247Sdamien	bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))
315145247Sdamien
316145247Sdamien#define CSR_READ_4(sc, reg)						\
317145247Sdamien	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
318145247Sdamien
319145247Sdamien#define CSR_WRITE_1(sc, reg, val)					\
320145247Sdamien	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
321145247Sdamien
322145247Sdamien#define CSR_WRITE_2(sc, reg, val)					\
323145247Sdamien	bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
324145247Sdamien
325145247Sdamien#define CSR_WRITE_4(sc, reg, val)					\
326145247Sdamien	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
327145247Sdamien
328145247Sdamien#define CSR_WRITE_MULTI_1(sc, reg, buf, len)				\
329145247Sdamien	bus_space_write_multi_1((sc)->sc_st, (sc)->sc_sh, (reg), 	\
330145247Sdamien	    (buf), (len))
331145247Sdamien
332145247Sdamien/*
333145247Sdamien * indirect memory space access macros
334145247Sdamien */
335156599Sdamien#define MEM_READ_1(sc, addr)						\
336156599Sdamien	(CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr)),		\
337156599Sdamien	 CSR_READ_1((sc), IPW_CSR_INDIRECT_DATA))
338156599Sdamien
339156599Sdamien#define MEM_READ_4(sc, addr)						\
340156599Sdamien	(CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr)),		\
341156599Sdamien	 CSR_READ_4((sc), IPW_CSR_INDIRECT_DATA))
342156599Sdamien
343145247Sdamien#define MEM_WRITE_1(sc, addr, val) do {					\
344145247Sdamien	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
345145247Sdamien	CSR_WRITE_1((sc), IPW_CSR_INDIRECT_DATA, (val));		\
346145247Sdamien} while (/* CONSTCOND */0)
347145247Sdamien
348145247Sdamien#define MEM_WRITE_2(sc, addr, val) do {					\
349145247Sdamien	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
350145247Sdamien	CSR_WRITE_2((sc), IPW_CSR_INDIRECT_DATA, (val));		\
351145247Sdamien} while (/* CONSTCOND */0)
352145247Sdamien
353145247Sdamien#define MEM_WRITE_4(sc, addr, val) do {					\
354145247Sdamien	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
355145247Sdamien	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_DATA, (val));		\
356145247Sdamien} while (/* CONSTCOND */0)
357145247Sdamien
358145247Sdamien#define MEM_WRITE_MULTI_1(sc, addr, buf, len) do {			\
359145247Sdamien	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
360145247Sdamien	CSR_WRITE_MULTI_1((sc), IPW_CSR_INDIRECT_DATA, (buf), (len));	\
361145247Sdamien} while (/* CONSTCOND */0)
362145247Sdamien
363145247Sdamien/*
364145247Sdamien * EEPROM access macro
365145247Sdamien */
366145247Sdamien#define IPW_EEPROM_CTL(sc, val) do {					\
367145247Sdamien	MEM_WRITE_4((sc), IPW_MEM_EEPROM_CTL, (val));			\
368145247Sdamien	DELAY(IPW_EEPROM_DELAY);					\
369145247Sdamien} while (0)
370