xref: /openbsd/sys/dev/pci/if_iwireg.h (revision 93e0ac5e)
1 /*	$OpenBSD: if_iwireg.h,v 1.28 2008/09/04 15:59:52 damien Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004-2008
5  *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #define IWI_CMD_RING_COUNT	16
21 #define IWI_TX_RING_COUNT	64
22 #define IWI_RX_RING_COUNT	32
23 
24 #define IWI_CSR_INTR		0x0008
25 #define IWI_CSR_INTR_MASK	0x000c
26 #define IWI_CSR_INDIRECT_ADDR	0x0010
27 #define IWI_CSR_INDIRECT_DATA	0x0014
28 #define IWI_CSR_AUTOINC_ADDR	0x0018
29 #define IWI_CSR_AUTOINC_DATA	0x001c
30 #define IWI_CSR_RST		0x0020
31 #define IWI_CSR_CTL		0x0024
32 #define IWI_CSR_IO		0x0030
33 #define IWI_CSR_CMD_BASE	0x0200
34 #define IWI_CSR_CMD_SIZE	0x0204
35 #define IWI_CSR_TX_BASE(ac)	(0x0208 + (ac) * 8)
36 #define IWI_CSR_TX_SIZE(ac)	(0x020c + (ac) * 8)
37 #define IWI_CSR_CMD_RIDX	0x0280
38 #define IWI_CSR_TX_RIDX(ac)	(0x0284 + (ac) * 4)
39 #define IWI_CSR_RX_RIDX		0x02a0
40 #define IWI_CSR_RX_BASE		0x0500
41 #define IWI_CSR_TABLE0_SIZE	0x0700
42 #define IWI_CSR_TABLE0_BASE	0x0704
43 #define IWI_CSR_NODE_BASE	0x0c0c
44 #define IWI_CSR_CMD_WIDX	0x0f80
45 #define IWI_CSR_TX_WIDX(ac)	(0x0f84 + (ac) * 4)
46 #define IWI_CSR_RX_WIDX		0x0fa0
47 #define IWI_CSR_READ_INT	0x0ff4
48 
49 /* aliases */
50 #define IWI_CSR_CURRENT_TX_RATE	IWI_CSR_TABLE0_BASE
51 
52 /* possible flags for IWI_CSR_INTR */
53 #define IWI_INTR_RX_DONE	0x00000002
54 #define IWI_INTR_CMD_DONE	0x00000800
55 #define IWI_INTR_TX1_DONE	0x00001000
56 #define IWI_INTR_TX2_DONE	0x00002000
57 #define IWI_INTR_TX3_DONE	0x00004000
58 #define IWI_INTR_TX4_DONE	0x00008000
59 #define IWI_INTR_FW_INITED	0x01000000
60 #define IWI_INTR_RADIO_OFF	0x04000000
61 #define IWI_INTR_FATAL_ERROR	0x40000000
62 #define IWI_INTR_PARITY_ERROR	0x80000000
63 
64 #define IWI_INTR_MASK							\
65 	(IWI_INTR_RX_DONE | IWI_INTR_CMD_DONE | IWI_INTR_TX1_DONE |	\
66 	 IWI_INTR_TX2_DONE | IWI_INTR_TX3_DONE | IWI_INTR_TX4_DONE |	\
67 	 IWI_INTR_FW_INITED | IWI_INTR_RADIO_OFF |			\
68 	 IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)
69 
70 /* possible flags for register IWI_CSR_RST */
71 #define IWI_RST_PRINCETON_RESET	0x00000001
72 #define IWI_RST_SW_RESET	0x00000080
73 #define IWI_RST_MASTER_DISABLED	0x00000100
74 #define IWI_RST_STOP_MASTER	0x00000200
75 
76 /* possible flags for register IWI_CSR_CTL */
77 #define IWI_CTL_CLOCK_READY	0x00000001
78 #define IWI_CTL_ALLOW_STANDBY	0x00000002
79 #define IWI_CTL_INIT		0x00000004
80 
81 /* possible flags for register IWI_CSR_IO */
82 #define IWI_IO_RADIO_ENABLED	0x00010000
83 
84 /* possible flags for IWI_CSR_READ_INT */
85 #define IWI_READ_INT_INIT_HOST	0x20000000
86 
87 /* constants for command blocks */
88 #define IWI_CB_DEFAULT_CTL	0x8cea0000
89 #define IWI_CB_MAXDATALEN	8191
90 
91 /* firmware binary image header */
92 struct iwi_firmware_hdr {
93 	uint8_t		oldvermaj;
94 	uint8_t		oldvermin;
95 	uint8_t		vermaj;
96 	uint8_t		vermin;
97 	uint32_t	bootsz;
98 	uint32_t	ucodesz;
99 	uint32_t	mainsz;
100 } __packed;
101 
102 struct iwi_hdr {
103 	uint8_t	type;
104 #define IWI_HDR_TYPE_DATA	0
105 #define IWI_HDR_TYPE_COMMAND	1
106 #define IWI_HDR_TYPE_NOTIF	3
107 #define IWI_HDR_TYPE_FRAME	9
108 
109 	uint8_t	seq;
110 	uint8_t	flags;
111 #define IWI_HDR_FLAG_IRQ	0x04
112 
113 	uint8_t	reserved;
114 } __packed;
115 
116 struct iwi_notif {
117 	uint32_t	reserved[2];
118 	uint8_t		type;
119 #define IWI_NOTIF_TYPE_ASSOCIATION	10
120 #define IWI_NOTIF_TYPE_AUTHENTICATION	11
121 #define IWI_NOTIF_TYPE_SCAN_CHANNEL	12
122 #define IWI_NOTIF_TYPE_SCAN_COMPLETE	13
123 #define IWI_NOTIF_TYPE_BAD_LINK		15
124 #define IWI_NOTIF_TYPE_BEACON		17
125 #define IWI_NOTIF_TYPE_PAIRWISE_KEY	18
126 #define IWI_NOTIF_TYPE_CALIBRATION	20
127 #define IWI_NOTIF_TYPE_NOISE		25
128 
129 	uint8_t		flags;
130 	uint16_t	len;
131 } __packed;
132 
133 /* structure for notification IWI_NOTIF_TYPE_AUTHENTICATION */
134 struct iwi_notif_authentication {
135 	uint8_t	state;
136 #define IWI_DEAUTHENTICATED	0
137 #define IWI_AUTHENTICATED	9
138 } __packed;
139 
140 /* structure for notification IWI_NOTIF_TYPE_ASSOCIATION */
141 struct iwi_notif_association {
142 	uint8_t			state;
143 #define IWI_DEASSOCIATED	0
144 #define IWI_ASSOCIATED		12
145 
146 	struct ieee80211_frame	frame;
147 	uint16_t		capinfo;
148 	uint16_t		status;
149 	uint16_t		associd;
150 } __packed;
151 
152 /* structure for notification IWI_NOTIF_TYPE_SCAN_CHANNEL */
153 struct iwi_notif_scan_channel {
154 	uint8_t	nchan;
155 	uint8_t	reserved[47];
156 } __packed;
157 
158 /* structure for notification IWI_NOTIF_TYPE_SCAN_COMPLETE */
159 struct iwi_notif_scan_complete {
160 	uint8_t	type;
161 	uint8_t	nchan;
162 	uint8_t	status;
163 	uint8_t	reserved;
164 } __packed;
165 
166 /* structure for notification IWI_NOTIF_TYPE_BEACON */
167 struct iwi_notif_beacon {
168 	uint32_t	status;
169 #define IWI_BEACON_MISSED	1
170 
171 	uint32_t	count;
172 };
173 
174 /* received frame header */
175 struct iwi_frame {
176 	uint32_t	reserved1[2];
177 	uint8_t		chan;
178 	uint8_t		status;
179 	uint8_t		rate;
180 	uint8_t		rssi;	/* receiver signal strength indicator */
181 	uint8_t		agc;	/* automatic gain control */
182 	uint8_t		rssi_dbm;
183 	uint16_t	signal;
184 	uint16_t	noise;
185 	uint8_t		antenna;
186 	uint8_t		control;
187 	uint8_t		reserved2[2];
188 	uint16_t	len;
189 } __packed;
190 
191 /* header for transmission */
192 struct iwi_tx_desc {
193 	struct iwi_hdr	hdr;
194 	uint32_t	reserved1;
195 	uint8_t		station;
196 	uint8_t		reserved2[3];
197 	uint8_t		cmd;
198 #define IWI_DATA_CMD_TX	0x0b
199 
200 	uint8_t		seq;
201 	uint16_t	len;
202 	uint8_t		priority;
203 	uint8_t		flags;
204 #define IWI_DATA_FLAG_SHPREAMBLE	(1 << 2)
205 #define IWI_DATA_FLAG_NO_WEP		(1 << 5)
206 #define IWI_DATA_FLAG_NEED_ACK		(1 << 7)
207 
208 	uint8_t		xflags;
209 #define IWI_DATA_XFLAG_CCK		(1 << 0)
210 #define IWI_DATA_XFLAG_QOS		(1 << 4)
211 
212 	uint8_t		txkey;
213 #define IWI_DATA_KEY_USE_PAIRWISE	(1 << 5)
214 #define IWI_DATA_KEY_WEP40		(1 << 6)
215 #define IWI_DATA_KEY_WEP104		(1 << 7)
216 
217 	uint8_t		wepkey[IEEE80211_KEYBUF_SIZE];
218 	uint8_t		rate;
219 	uint8_t		antenna;
220 	uint8_t		reserved3[10];
221 
222 	struct ieee80211_qosframe_addr4	wh;
223 	uint32_t	iv[2];
224 
225 	uint32_t	nseg;
226 #define IWI_MAX_NSEG	6
227 #define IWI_MAX_SCATTER	(IWI_MAX_NSEG - 2)
228 
229 	uint32_t	seg_addr[IWI_MAX_NSEG];
230 	uint16_t	seg_len[IWI_MAX_NSEG];
231 } __packed;
232 
233 /* command */
234 struct iwi_cmd_desc {
235 	struct iwi_hdr	hdr;
236 	uint8_t		type;
237 #define IWI_CMD_ENABLE			2
238 #define IWI_CMD_SET_CONFIG		6
239 #define IWI_CMD_SET_ESSID		8
240 #define IWI_CMD_SET_MAC_ADDRESS		11
241 #define IWI_CMD_SET_RTS_THRESHOLD	15
242 #define IWI_CMD_SET_FRAG_THRESHOLD	16
243 #define IWI_CMD_SET_POWER_MODE		17
244 #define IWI_CMD_SET_GROUP_KEY		18
245 #define IWI_CMD_SET_PAIRWISE_KEY	19
246 #define IWI_CMD_ASSOCIATE		21
247 #define IWI_CMD_SET_RATES		22
248 #define IWI_CMD_SET_QOS_PARAMS		25
249 #define IWI_CMD_SCAN			26
250 #define IWI_CMD_SET_OPTIE		31
251 #define IWI_CMD_DISABLE			33
252 #define IWI_CMD_SET_RANDOM_SEED		34
253 #define IWI_CMD_SET_TX_POWER		35
254 #define IWI_CMD_SET_SENSITIVITY		42
255 #define IWI_CMD_SET_QOS_CAP		84
256 
257 	uint8_t		len;
258 	uint16_t	reserved;
259 	uint8_t		data[120];
260 } __packed;
261 
262 /* node information (IBSS) */
263 struct iwi_node {
264 	uint8_t	bssid[IEEE80211_ADDR_LEN];
265 	uint8_t	reserved[2];
266 } __packed;
267 
268 /* constants for 'mode' fields */
269 #define IWI_MODE_11A	0
270 #define IWI_MODE_11B	1
271 #define IWI_MODE_11G	2
272 
273 /* possible values for command IWI_CMD_SET_POWER_MODE */
274 #define IWI_POWER_MODE_CAM	0
275 
276 /* structure for command IWI_CMD_SET_RATES */
277 struct iwi_rateset {
278 	uint8_t	mode;
279 	uint8_t	nrates;
280 	uint8_t	type;
281 #define IWI_RATESET_TYPE_NEGOTIATED	0
282 #define IWI_RATESET_TYPE_SUPPORTED	1
283 
284 	uint8_t	reserved;
285 	uint8_t	rates[12];
286 } __packed;
287 
288 /* structures for command IWI_CMD_SET_QOS_PARAMS */
289 struct iwi_qos_params {
290 	uint16_t	cwmin[EDCA_NUM_AC];
291 	uint16_t	cwmax[EDCA_NUM_AC];
292 	uint8_t		aifsn[EDCA_NUM_AC];
293 	uint8_t		acm  [EDCA_NUM_AC];
294 	uint8_t		txop [EDCA_NUM_AC];
295 } __packed;
296 
297 struct iwi_qos_cmd {
298 	struct iwi_qos_params	cck;
299 	struct iwi_qos_params	ofdm;
300 	struct iwi_qos_params	current;
301 } __packed;
302 
303 /* copied verbatim from sys/net80211/ieee80211_output.c */
304 static const struct ieee80211_edca_ac_params iwi_cck[EDCA_NUM_AC] = {
305 	[EDCA_AC_BK] = { 5, 10, 7,   0 },
306 	[EDCA_AC_BE] = { 5, 10, 3,   0 },
307 	[EDCA_AC_VI] = { 4,  5, 2, 188 },
308 	[EDCA_AC_VO] = { 3,  4, 2, 102 }
309 };
310 
311 /* copied verbatim from sys/net80211/ieee80211_output.c */
312 static const struct ieee80211_edca_ac_params iwi_ofdm[EDCA_NUM_AC] = {
313 	[EDCA_AC_BK] = { 4, 10, 7,   0 },
314 	[EDCA_AC_BE] = { 4, 10, 3,   0 },
315 	[EDCA_AC_VI] = { 3,  4, 2,  94 },
316 	[EDCA_AC_VO] = { 2,  3, 2,  47 }
317 };
318 
319 /* structure for command IWI_CMD_SET_TX_POWER */
320 struct iwi_txpower {
321 	uint8_t	nchan;
322 	uint8_t	mode;
323 	struct {
324 		uint8_t	chan;
325 		uint8_t	power;
326 #define IWI_TXPOWER_MAX		20
327 #define IWI_TXPOWER_RATIO	(IEEE80211_TXPOWER_MAX / IWI_TXPOWER_MAX)
328 	} __packed chan[37];
329 } __packed;
330 
331 /* structure for command IWI_CMD_ASSOCIATE */
332 struct iwi_associate {
333 	uint8_t		chan;
334 	uint8_t		auth;
335 #define IWI_AUTH_OPEN	0
336 #define IWI_AUTH_SHARED	1
337 #define IWI_AUTH_NONE	3
338 
339 	uint8_t		type;
340 #define IWI_ASSOC_ASSOCIATE	0
341 #define IWI_ASSOC_REASSOCIATE	1
342 #define IWI_ASSOC_DISASSOCIATE	2
343 #define IWI_ASSOC_SIBSS		3
344 
345 	uint8_t		reserved1;
346 	uint16_t	policy;
347 #define IWI_ASSOC_POLICY_QOS	(1 << 0)
348 #define IWI_ASSOC_POLICY_RSN	(1 << 1)
349 
350 	uint8_t		plen;
351 #define IWI_ASSOC_SHPREAMBLE	(1 << 2)
352 
353 	uint8_t		mode;
354 	uint8_t		bssid[IEEE80211_ADDR_LEN];
355 	uint8_t		tstamp[8];
356 	uint16_t	capinfo;
357 	uint16_t	lintval;
358 	uint16_t	intval;
359 	uint8_t		dst[IEEE80211_ADDR_LEN];
360 	uint32_t	reserved3;
361 	uint16_t	reserved4;
362 } __packed;
363 
364 /* structure for command IWI_CMD_SCAN */
365 struct iwi_scan {
366 	uint32_t	index;
367 	uint8_t		channels[54];
368 #define IWI_CHAN_5GHZ	(0 << 6)
369 #define IWI_CHAN_2GHZ	(1 << 6)
370 
371 	uint8_t		type[27];
372 #define IWI_SCAN_TYPE_PASSIVE	0x11
373 #define IWI_SCAN_TYPE_DIRECTED	0x22
374 #define IWI_SCAN_TYPE_BROADCAST	0x33
375 #define IWI_SCAN_TYPE_BDIRECTED	0x44
376 
377 	uint8_t		reserved1;
378 	uint16_t	reserved2;
379 	uint16_t	passive;	/* dwell time */
380 	uint16_t	directed;	/* dwell time */
381 	uint16_t	broadcast;	/* dwell time */
382 	uint16_t	bdirected;	/* dwell time */
383 } __packed;
384 
385 /* structure for command IWI_CMD_SET_CONFIGURATION */
386 struct iwi_configuration {
387 	uint8_t	bluetooth_coexistence;
388 	uint8_t	reserved1;
389 	uint8_t	answer_pbreq;
390 	uint8_t	allow_invalid_frames;
391 	uint8_t	multicast_enabled;
392 	uint8_t	exclude_unicast_unencrypted;
393 	uint8_t	disable_unicast_decryption;
394 	uint8_t	exclude_multicast_unencrypted;
395 	uint8_t	disable_multicast_decryption;
396 	uint8_t	antenna;
397 	uint8_t	reserved2;
398 	uint8_t	bg_autodetection;
399 	uint8_t	reserved3;
400 	uint8_t	enable_multicast_filtering;
401 	uint8_t	bluetooth_threshold;
402 	uint8_t	silence_threshold;
403 	uint8_t	allow_beacon_and_probe_resp;
404 	uint8_t	allow_mgt;
405 	uint8_t	report_noise;
406 	uint8_t	reserved5;
407 } __packed;
408 
409 /* structure for command IWI_CMD_SET_GROUP_KEY */
410 struct iwi_group_key {
411 	uint8_t	cmd;
412 #define IWI_GROUP_KEY_CMD_SETKEY	0x08
413 
414 	uint8_t	seq;
415 	uint8_t	idx;
416 	uint8_t	len;
417 	uint8_t	key[16];
418 } __packed;
419 
420 /* structure for command IWI_CMD_SET_PAIRWISE_KEY */
421 struct iwi_pairwise_key {
422 	uint8_t		idx;
423 	uint8_t		cipher;
424 #define IWI_CIPHER_WEP	0
425 #define IWI_CIPHER_CCMP	2
426 #define IWI_CIPHER_TKIP	3
427 	uint8_t		sta;
428 	uint8_t		flags;
429 	uint8_t		key[16];
430 	uint64_t	tsc;
431 } __packed;
432 
433 #define IWI_MEM_EEPROM_CTL	0x00300040
434 #define IWI_MEM_EVENT_CTL	0x00300004
435 
436 /* possible flags for register IWI_MEM_EVENT */
437 #define IWI_LED_ASSOC	(1 << 5)
438 #define IWI_LED_MASK	0xd9fffffb
439 
440 /* EEPROM = Electrically Erasable Programmable Read-Only Memory */
441 
442 #define IWI_EEPROM_MAC	0x21
443 
444 #define IWI_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
445 
446 #define IWI_EEPROM_C	(1 << 0)	/* Serial Clock */
447 #define IWI_EEPROM_S	(1 << 1)	/* Chip Select */
448 #define IWI_EEPROM_D	(1 << 2)	/* Serial data input */
449 #define IWI_EEPROM_Q	(1 << 4)	/* Serial data output */
450 
451 #define IWI_EEPROM_SHIFT_D	2
452 #define IWI_EEPROM_SHIFT_Q	4
453 
454 /*
455  * control and status registers access macros
456  */
457 #define CSR_READ_1(sc, reg)						\
458 	bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
459 
460 #define CSR_READ_2(sc, reg)						\
461 	bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))
462 
463 #define CSR_READ_4(sc, reg)						\
464 	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
465 
466 #define CSR_READ_REGION_4(sc, offset, datap, count)			\
467 	bus_space_read_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
468 	    (datap), (count))
469 
470 #define CSR_WRITE_1(sc, reg, val)					\
471 	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
472 
473 #define CSR_WRITE_2(sc, reg, val)					\
474 	bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
475 
476 #define CSR_WRITE_4(sc, reg, val)					\
477 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
478 
479 #define CSR_WRITE_REGION_1(sc, offset, datap, count)			\
480 	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
481 	    (datap), (count))
482 /*
483  * indirect memory space access macros
484  */
485 #define MEM_WRITE_1(sc, addr, val) do {					\
486 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
487 	CSR_WRITE_1((sc), IWI_CSR_INDIRECT_DATA, (val));		\
488 } while (/* CONSTCOND */0)
489 
490 #define MEM_WRITE_2(sc, addr, val) do {					\
491 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
492 	CSR_WRITE_2((sc), IWI_CSR_INDIRECT_DATA, (val));		\
493 } while (/* CONSTCOND */0)
494 
495 #define MEM_WRITE_4(sc, addr, val) do {					\
496 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
497 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_DATA, (val));		\
498 } while (/* CONSTCOND */0)
499 
500 #define MEM_WRITE_MULTI_1(sc, addr, buf, len) do {			\
501 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
502 	CSR_WRITE_MULTI_1((sc), IWI_CSR_INDIRECT_DATA, (buf), (len));	\
503 } while (/* CONSTCOND */0)
504 
505 /*
506  * EEPROM access macro
507  */
508 #define IWI_EEPROM_CTL(sc, val) do {					\
509 	MEM_WRITE_4((sc), IWI_MEM_EEPROM_CTL, (val));			\
510 	DELAY(IWI_EEPROM_DELAY);					\
511 } while (/* CONSTCOND */0)
512