summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_ipwreg.h
blob: 9cda8b48ba3dcc054438c1729f20d46ad32eb35f (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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*	$OpenBSD: if_ipwreg.h,v 1.11 2005/01/13 20:52:13 damien Exp $	*/

/*-
 * Copyright (c) 2004, 2005
 *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice unmodified, this list of conditions, and the following
 *    disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#define IPW_NTBD	128
#define IPW_TBD_SZ	(IPW_NTBD * sizeof (struct ipw_bd))
#define IPW_NDATA	(IPW_NTBD / 2)
#define IPW_NRBD	128
#define IPW_RBD_SZ	(IPW_NRBD * sizeof (struct ipw_bd))
#define IPW_STATUS_SZ	(IPW_NRBD * sizeof (struct ipw_status))

#define IPW_CSR_INTR		0x0008
#define IPW_CSR_INTR_MASK	0x000c
#define IPW_CSR_INDIRECT_ADDR	0x0010
#define IPW_CSR_INDIRECT_DATA	0x0014
#define IPW_CSR_AUTOINC_ADDR	0x0018
#define IPW_CSR_AUTOINC_DATA	0x001c
#define IPW_CSR_RST		0x0020
#define IPW_CSR_CTL		0x0024
#define IPW_CSR_IO		0x0030
#define IPW_CSR_TX_BD_BASE	0x0200
#define IPW_CSR_TX_BD_SIZE	0x0204
#define IPW_CSR_RX_BD_BASE	0x0240
#define IPW_CSR_RX_STATUS_BASE	0x0244
#define IPW_CSR_RX_BD_SIZE	0x0248
#define IPW_CSR_TX_READ_INDEX	0x0280
#define IPW_CSR_RX_READ_INDEX	0x02a0
#define IPW_CSR_TABLE1_BASE	0x0380
#define IPW_CSR_TABLE2_BASE	0x0384
#define IPW_CSR_TX_WRITE_INDEX	0x0f80
#define IPW_CSR_RX_WRITE_INDEX	0x0fa0

/* possible flags for register IPW_CSR_INTR */
#define IPW_INTR_TX_TRANSFER	0x00000001
#define IPW_INTR_RX_TRANSFER	0x00000002
#define IPW_INTR_STATUS_CHANGE	0x00000010
#define IPW_INTR_COMMAND_DONE	0x00010000
#define IPW_INTR_FW_INIT_DONE	0x01000000
#define IPW_INTR_FATAL_ERROR	0x40000000
#define IPW_INTR_PARITY_ERROR	0x80000000

#define IPW_INTR_MASK							\
	(IPW_INTR_TX_TRANSFER | IPW_INTR_RX_TRANSFER |			\
	 IPW_INTR_STATUS_CHANGE | IPW_INTR_COMMAND_DONE |		\
	 IPW_INTR_FW_INIT_DONE | IPW_INTR_FATAL_ERROR |			\
	 IPW_INTR_PARITY_ERROR)

/* possible flags for register IPW_CSR_RST */
#define IPW_RST_PRINCETON_RESET	0x00000001
#define IPW_RST_SW_RESET	0x00000080
#define IPW_RST_MASTER_DISABLED	0x00000100
#define IPW_RST_STOP_MASTER	0x00000200

/* possible flags for register IPW_CSR_CTL */
#define IPW_CTL_CLOCK_READY	0x00000001
#define IPW_CTL_ALLOW_STANDBY	0x00000002
#define IPW_CTL_INIT		0x00000004

/* possible flags for register IPW_CSR_IO */
#define IPW_IO_GPIO1_ENABLE	0x00000008
#define IPW_IO_GPIO1_MASK	0x0000000c
#define IPW_IO_GPIO3_MASK	0x000000c0
#define IPW_IO_LED_OFF		0x00002000
#define IPW_IO_RADIO_DISABLED	0x00010000

#define IPW_STATE_ASSOCIATED		0x0004
#define IPW_STATE_ASSOCIATION_LOST	0x0008
#define IPW_STATE_SCAN_COMPLETE		0x0020
#define IPW_STATE_RADIO_DISABLED	0x0100
#define IPW_STATE_DISABLED		0x0200
#define IPW_STATE_SCANNING		0x0800

/* table1 offsets */
#define IPW_INFO_LOCK			480
#define IPW_INFO_APS_CNT		604
#define IPW_INFO_APS_BASE		608
#define IPW_INFO_CARD_DISABLED		628
#define IPW_INFO_CURRENT_CHANNEL	756
#define IPW_INFO_CURRENT_TX_RATE	768

/* table2 offsets */
#define IPW_INFO_CURRENT_SSID	48
#define IPW_INFO_CURRENT_BSSID	112

/* supported rates */
#define IPW_RATE_DS1	1
#define IPW_RATE_DS2	2
#define IPW_RATE_DS5	4
#define IPW_RATE_DS11	8

/* firmware binary image header */
struct ipw_firmware_hdr {
	u_int32_t	version;
	u_int32_t	main_size;	/* firmware size */
	u_int32_t	ucode_size;	/* microcode size */
} __attribute__((__packed__));

/* buffer descriptor */
struct ipw_bd {
	u_int32_t	physaddr;
	u_int32_t	len;
	u_int8_t	flags;
#define IPW_BD_FLAG_TX_FRAME_802_3		0x00
#define IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT	0x01
#define IPW_BD_FLAG_TX_FRAME_COMMAND		0x02
#define IPW_BD_FLAG_TX_FRAME_802_11		0x04
#define IPW_BD_FLAG_TX_LAST_FRAGMENT		0x08
	u_int8_t	nfrag;	/* number of fragments */
	u_int8_t	reserved[6];
} __attribute__((__packed__));

/* status */
struct ipw_status {
	u_int32_t	len;
	u_int16_t	code;
#define IPW_STATUS_CODE_COMMAND		0
#define IPW_STATUS_CODE_NEWSTATE	1
#define IPW_STATUS_CODE_DATA_802_11	2
#define IPW_STATUS_CODE_DATA_802_3	3
#define IPW_STATUS_CODE_NOTIFICATION	4
	u_int8_t	flags;
#define IPW_STATUS_FLAG_DECRYPTED	0x01
#define IPW_STATUS_FLAG_WEP_ENCRYPTED	0x02
	u_int8_t	rssi;	/* received signal strength indicator */
} __attribute__((__packed__));

/* data header */
struct ipw_hdr {
	u_int32_t	type;
#define IPW_HDR_TYPE_SEND	33
	u_int32_t	subtype;
	u_int8_t	encrypted;
	u_int8_t	encrypt;
	u_int8_t	keyidx;
	u_int8_t	keysz;
	u_int8_t	key[IEEE80211_KEYBUF_SIZE];
	u_int8_t	reserved[10];
	u_int8_t	src_addr[IEEE80211_ADDR_LEN];
	u_int8_t	dst_addr[IEEE80211_ADDR_LEN];
	u_int16_t	fragmentsz;
} __attribute__((__packed__));

/* command */
struct ipw_cmd {
	u_int32_t	type;
#define IPW_CMD_ENABLE				2
#define IPW_CMD_SET_CONFIGURATION		6
#define IPW_CMD_SET_ESSID			8
#define IPW_CMD_SET_MANDATORY_BSSID		9
#define IPW_CMD_SET_MAC_ADDRESS			11
#define IPW_CMD_SET_MODE			12
#define IPW_CMD_SET_CHANNEL			14
#define IPW_CMD_SET_RTS_THRESHOLD		15
#define IPW_CMD_SET_FRAG_THRESHOLD		16
#define IPW_CMD_SET_POWER_MODE			17
#define IPW_CMD_SET_TX_RATES			18
#define IPW_CMD_SET_BASIC_TX_RATES		19
#define IPW_CMD_SET_WEP_KEY			20
#define IPW_CMD_SET_WEP_KEY_INDEX		25
#define IPW_CMD_SET_WEP_FLAGS			26
#define IPW_CMD_ADD_MULTICAST			27
#define IPW_CMD_SET_BEACON_INTERVAL		29
#define IPW_CMD_SET_TX_POWER_INDEX		36
#define IPW_CMD_BROADCAST_SCAN			43
#define IPW_CMD_DISABLE				44
#define IPW_CMD_SET_DESIRED_BSSID		45
#define IPW_CMD_SET_SCAN_OPTIONS		46
#define IPW_CMD_PREPARE_POWER_DOWN		58
#define IPW_CMD_DISABLE_PHY			61
#define IPW_CMD_SET_SECURITY_INFORMATION	67
	u_int32_t	subtype;
	u_int32_t	seq;
	u_int32_t	len;
	u_int8_t	data[400];
	u_int32_t	status;
	u_int8_t	reserved[68];
} __attribute__((__packed__));

/* possible values for command IPW_CMD_SET_POWER_MODE */
#define IPW_POWER_MODE_CAM	0
#define IPW_POWER_AUTOMATIC	6

/* possible values for command IPW_CMD_SET_MODE */
#define IPW_MODE_BSS		0
#define IPW_MODE_IBSS		1
#define IPW_MODE_MONITOR	2

/* possible flags for command IPW_CMD_SET_WEP_FLAGS */
#define IPW_WEPON	0x8

/* structure for command IPW_CMD_SET_WEP_KEY */
struct ipw_wep_key {
	u_int8_t	idx;
	u_int8_t	len;
	u_int8_t	key[13];
} __attribute__((__packed__));

/* structure for command IPW_CMD_SET_SECURITY_INFORMATION */
struct ipw_security {
	u_int32_t	ciphers;
#define IPW_CIPHER_NONE		0x00000001
#define IPW_CIPHER_WEP40	0x00000002
#define IPW_CIPHER_WEP104	0x00000020
	u_int16_t	reserved1;
	u_int8_t	authmode;
#define IPW_AUTH_OPEN	0
#define IPW_AUTH_SHARED	1
	u_int16_t	reserved2;
} __attribute__((__packed__));

/* structure for command IPW_CMD_SET_SCAN_OPTIONS */
struct ipw_scan_options {
	u_int32_t	flags;
#define IPW_SCAN_DO_NOT_ASSOCIATE	0x00000001
#define IPW_SCAN_PASSIVE		0x00000008
	u_int32_t	channels;
} __attribute__((__packed__));

/* structure for command IPW_CMD_SET_CONFIGURATION */
struct ipw_configuration {
	u_int32_t	flags;
#define IPW_CFG_PROMISCUOUS	0x00000004
#define IPW_CFG_PREAMBLE_AUTO	0x00000010
#define IPW_CFG_IBSS_AUTO_START	0x00000020
#define IPW_CFG_802_1x_ENABLE	0x00004000
#define IPW_CFG_BSS_MASK	0x00008000
#define IPW_CFG_IBSS_MASK	0x00010000
	u_int32_t	bss_chan;
	u_int32_t	ibss_chan;
} __attribute__((__packed__));

/* element in AP table */
struct ipw_node {
	u_int32_t	reserved1[2];
	u_int8_t	bssid[IEEE80211_ADDR_LEN];
	u_int8_t	chan;
	u_int8_t	rates;
	u_int16_t	reserved2;
	u_int16_t	capinfo;
	u_int16_t	reserved3;
	u_int16_t	intval;
	u_int8_t	reserved4[28];
	u_int8_t	essid[IEEE80211_NWID_LEN];
	u_int16_t	reserved5;
	u_int8_t	esslen;
	u_int8_t	reserved6[7];
	u_int8_t	rssi;
} __attribute__((__packed__));

/* EEPROM = Electrically Erasable Programmable Read-Only Memory */

#define IPW_MEM_EEPROM_CTL	0x00300040

#define IPW_EEPROM_MAC	0x21

#define IPW_EEPROM_DELAY	1	/* minimum hold time (microsecond) */

#define IPW_EEPROM_C	(1 << 0)	/* Serial Clock */
#define IPW_EEPROM_S	(1 << 1)	/* Chip Select */
#define IPW_EEPROM_D	(1 << 2)	/* Serial data input */
#define IPW_EEPROM_Q	(1 << 4)	/* Serial data output */

#define IPW_EEPROM_SHIFT_D	2
#define IPW_EEPROM_SHIFT_Q	4

/*
 * control and status registers access macros
 */
#define CSR_READ_1(sc, reg)						\
	bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))

#define CSR_READ_2(sc, reg)						\
	bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))

#define CSR_READ_4(sc, reg)						\
	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))

#define CSR_WRITE_1(sc, reg, val)					\
	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))

#define CSR_WRITE_2(sc, reg, val)					\
	bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))

#define CSR_WRITE_4(sc, reg, val)					\
	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))

#define CSR_WRITE_MULTI_1(sc, reg, buf, len)				\
	bus_space_write_multi_1((sc)->sc_st, (sc)->sc_sh, (reg), 	\
	    (buf), (len))

/*
 * indirect memory space access macros
 */
#define MEM_WRITE_1(sc, addr, val) do {					\
	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
	CSR_WRITE_1((sc), IPW_CSR_INDIRECT_DATA, (val));		\
} while (/* CONSTCOND */0)

#define MEM_WRITE_2(sc, addr, val) do {					\
	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
	CSR_WRITE_2((sc), IPW_CSR_INDIRECT_DATA, (val));		\
} while (/* CONSTCOND */0)

#define MEM_WRITE_4(sc, addr, val) do {					\
	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_DATA, (val));		\
} while (/* CONSTCOND */0)

#define MEM_WRITE_MULTI_1(sc, addr, buf, len) do {			\
	CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr));		\
	CSR_WRITE_MULTI_1((sc), IPW_CSR_INDIRECT_DATA, (buf), (len));	\
} while (/* CONSTCOND */0)

/*
 * EEPROM access macro
 */
#define IPW_EEPROM_CTL(sc, val) do {					\
	MEM_WRITE_4((sc), IPW_MEM_EEPROM_CTL, (val));			\
	DELAY(IPW_EEPROM_DELAY);					\
} while (0)