xref: /freebsd/sys/dev/iwi/if_iwireg.h (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
1ceaec73dSDamien Bergamini 
2ceaec73dSDamien Bergamini /*-
3*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
4718cf2ccSPedro F. Giffuni  *
5c10b1400SMax Laier  * Copyright (c) 2004, 2005
6ceaec73dSDamien Bergamini  *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
7ceaec73dSDamien Bergamini  *
8ceaec73dSDamien Bergamini  * Redistribution and use in source and binary forms, with or without
9ceaec73dSDamien Bergamini  * modification, are permitted provided that the following conditions
10ceaec73dSDamien Bergamini  * are met:
11ceaec73dSDamien Bergamini  * 1. Redistributions of source code must retain the above copyright
12ceaec73dSDamien Bergamini  *    notice unmodified, this list of conditions, and the following
13ceaec73dSDamien Bergamini  *    disclaimer.
14ceaec73dSDamien Bergamini  * 2. Redistributions in binary form must reproduce the above copyright
15ceaec73dSDamien Bergamini  *    notice, this list of conditions and the following disclaimer in the
16ceaec73dSDamien Bergamini  *    documentation and/or other materials provided with the distribution.
17ceaec73dSDamien Bergamini  *
18ceaec73dSDamien Bergamini  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19ceaec73dSDamien Bergamini  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20ceaec73dSDamien Bergamini  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21ceaec73dSDamien Bergamini  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22ceaec73dSDamien Bergamini  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23ceaec73dSDamien Bergamini  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24ceaec73dSDamien Bergamini  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25ceaec73dSDamien Bergamini  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26ceaec73dSDamien Bergamini  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27ceaec73dSDamien Bergamini  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28ceaec73dSDamien Bergamini  * SUCH DAMAGE.
29ceaec73dSDamien Bergamini  */
30ceaec73dSDamien Bergamini 
31ceaec73dSDamien Bergamini #define IWI_CMD_RING_COUNT	16
32ceaec73dSDamien Bergamini #define IWI_TX_RING_COUNT	64
33ceaec73dSDamien Bergamini #define IWI_RX_RING_COUNT	32
34ceaec73dSDamien Bergamini 
35ceaec73dSDamien Bergamini #define IWI_TX_DESC_SIZE	(sizeof (struct iwi_tx_desc))
36ceaec73dSDamien Bergamini #define IWI_CMD_DESC_SIZE	(sizeof (struct iwi_cmd_desc))
37ceaec73dSDamien Bergamini 
38ceaec73dSDamien Bergamini #define IWI_CSR_INTR		0x0008
39ceaec73dSDamien Bergamini #define IWI_CSR_INTR_MASK	0x000c
40ceaec73dSDamien Bergamini #define IWI_CSR_INDIRECT_ADDR	0x0010
41ceaec73dSDamien Bergamini #define IWI_CSR_INDIRECT_DATA	0x0014
42ceaec73dSDamien Bergamini #define IWI_CSR_AUTOINC_ADDR	0x0018
43ceaec73dSDamien Bergamini #define IWI_CSR_AUTOINC_DATA	0x001c
44ceaec73dSDamien Bergamini #define IWI_CSR_RST		0x0020
45ceaec73dSDamien Bergamini #define IWI_CSR_CTL		0x0024
46ceaec73dSDamien Bergamini #define IWI_CSR_IO		0x0030
47ceaec73dSDamien Bergamini #define IWI_CSR_CMD_BASE	0x0200
48ceaec73dSDamien Bergamini #define IWI_CSR_CMD_SIZE	0x0204
49ceaec73dSDamien Bergamini #define IWI_CSR_TX1_BASE	0x0208
50ceaec73dSDamien Bergamini #define IWI_CSR_TX1_SIZE	0x020c
51ceaec73dSDamien Bergamini #define IWI_CSR_TX2_BASE	0x0210
52ceaec73dSDamien Bergamini #define IWI_CSR_TX2_SIZE	0x0214
53ceaec73dSDamien Bergamini #define IWI_CSR_TX3_BASE	0x0218
54ceaec73dSDamien Bergamini #define IWI_CSR_TX3_SIZE	0x021c
55ceaec73dSDamien Bergamini #define IWI_CSR_TX4_BASE	0x0220
56ceaec73dSDamien Bergamini #define IWI_CSR_TX4_SIZE	0x0224
57ceaec73dSDamien Bergamini #define IWI_CSR_CMD_RIDX	0x0280
58ceaec73dSDamien Bergamini #define IWI_CSR_TX1_RIDX	0x0284
59ceaec73dSDamien Bergamini #define IWI_CSR_TX2_RIDX	0x0288
60ceaec73dSDamien Bergamini #define IWI_CSR_TX3_RIDX	0x028c
61ceaec73dSDamien Bergamini #define IWI_CSR_TX4_RIDX	0x0290
62ceaec73dSDamien Bergamini #define IWI_CSR_RX_RIDX		0x02a0
63ceaec73dSDamien Bergamini #define IWI_CSR_RX_BASE		0x0500
64ceaec73dSDamien Bergamini #define IWI_CSR_TABLE0_SIZE	0x0700
65ceaec73dSDamien Bergamini #define IWI_CSR_TABLE0_BASE	0x0704
660b74a285SDamien Bergamini #define IWI_CSR_NODE_BASE	0x0c0c
67ceaec73dSDamien Bergamini #define IWI_CSR_CMD_WIDX	0x0f80
68ceaec73dSDamien Bergamini #define IWI_CSR_TX1_WIDX	0x0f84
69ceaec73dSDamien Bergamini #define IWI_CSR_TX2_WIDX	0x0f88
70ceaec73dSDamien Bergamini #define IWI_CSR_TX3_WIDX	0x0f8c
71ceaec73dSDamien Bergamini #define IWI_CSR_TX4_WIDX	0x0f90
72ceaec73dSDamien Bergamini #define IWI_CSR_RX_WIDX		0x0fa0
73ceaec73dSDamien Bergamini #define IWI_CSR_READ_INT	0x0ff4
74ceaec73dSDamien Bergamini 
75ceaec73dSDamien Bergamini /* aliases */
76ceaec73dSDamien Bergamini #define IWI_CSR_CURRENT_TX_RATE	IWI_CSR_TABLE0_BASE
77ceaec73dSDamien Bergamini 
78ceaec73dSDamien Bergamini /* flags for IWI_CSR_INTR */
79ceaec73dSDamien Bergamini #define IWI_INTR_RX_DONE	0x00000002
80ceaec73dSDamien Bergamini #define IWI_INTR_CMD_DONE	0x00000800
81ceaec73dSDamien Bergamini #define IWI_INTR_TX1_DONE	0x00001000
82ceaec73dSDamien Bergamini #define IWI_INTR_TX2_DONE	0x00002000
83ceaec73dSDamien Bergamini #define IWI_INTR_TX3_DONE	0x00004000
84ceaec73dSDamien Bergamini #define IWI_INTR_TX4_DONE	0x00008000
85ceaec73dSDamien Bergamini #define IWI_INTR_FW_INITED	0x01000000
86ceaec73dSDamien Bergamini #define IWI_INTR_RADIO_OFF	0x04000000
87ceaec73dSDamien Bergamini #define IWI_INTR_FATAL_ERROR	0x40000000
88ceaec73dSDamien Bergamini #define IWI_INTR_PARITY_ERROR	0x80000000
89ceaec73dSDamien Bergamini 
90ceaec73dSDamien Bergamini #define IWI_INTR_MASK							\
91ceaec73dSDamien Bergamini 	(IWI_INTR_RX_DONE | IWI_INTR_CMD_DONE |	IWI_INTR_TX1_DONE | 	\
92ceaec73dSDamien Bergamini 	 IWI_INTR_TX2_DONE | IWI_INTR_TX3_DONE | IWI_INTR_TX4_DONE |	\
93ceaec73dSDamien Bergamini 	 IWI_INTR_FW_INITED | IWI_INTR_RADIO_OFF |			\
94ceaec73dSDamien Bergamini 	 IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)
95ceaec73dSDamien Bergamini 
96ceaec73dSDamien Bergamini /* flags for IWI_CSR_RST */
97ceaec73dSDamien Bergamini #define IWI_RST_PRINCETON_RESET	0x00000001
98c10b1400SMax Laier #define	IWI_RST_STANDBY		0x00000004
99c10b1400SMax Laier #define	IWI_RST_LED_ACTIVITY	0x00000010	/* tx/rx traffic led */
100c10b1400SMax Laier #define	IWI_RST_LED_ASSOCIATED	0x00000020	/* station associated led */
101c10b1400SMax Laier #define	IWI_RST_LED_OFDM	0x00000040	/* ofdm/cck led */
102ceaec73dSDamien Bergamini #define IWI_RST_SOFT_RESET	0x00000080
103ceaec73dSDamien Bergamini #define IWI_RST_MASTER_DISABLED	0x00000100
104ceaec73dSDamien Bergamini #define IWI_RST_STOP_MASTER	0x00000200
105c10b1400SMax Laier #define IWI_RST_GATE_ODMA	0x02000000
106c10b1400SMax Laier #define IWI_RST_GATE_IDMA	0x04000000
107c10b1400SMax Laier #define IWI_RST_GATE_ADMA	0x20000000
108ceaec73dSDamien Bergamini 
109ceaec73dSDamien Bergamini /* flags for IWI_CSR_CTL */
110ceaec73dSDamien Bergamini #define IWI_CTL_CLOCK_READY	0x00000001
111ceaec73dSDamien Bergamini #define IWI_CTL_ALLOW_STANDBY	0x00000002
112ceaec73dSDamien Bergamini #define IWI_CTL_INIT		0x00000004
113ceaec73dSDamien Bergamini 
114ceaec73dSDamien Bergamini /* flags for IWI_CSR_IO */
115ceaec73dSDamien Bergamini #define IWI_IO_RADIO_ENABLED	0x00010000
116ceaec73dSDamien Bergamini 
117ceaec73dSDamien Bergamini /* flags for IWI_CSR_READ_INT */
118ceaec73dSDamien Bergamini #define IWI_READ_INT_INIT_HOST	0x20000000
119ceaec73dSDamien Bergamini 
120ceaec73dSDamien Bergamini /* constants for command blocks */
121ceaec73dSDamien Bergamini #define IWI_CB_DEFAULT_CTL	0x8cea0000
122ceaec73dSDamien Bergamini #define IWI_CB_MAXDATALEN	8191
123ceaec73dSDamien Bergamini 
124ceaec73dSDamien Bergamini /* supported rates */
125ceaec73dSDamien Bergamini #define IWI_RATE_DS1	10
126ceaec73dSDamien Bergamini #define IWI_RATE_DS2	20
127ceaec73dSDamien Bergamini #define IWI_RATE_DS5	55
128ceaec73dSDamien Bergamini #define IWI_RATE_DS11	110
129ceaec73dSDamien Bergamini #define IWI_RATE_OFDM6	13
130ceaec73dSDamien Bergamini #define IWI_RATE_OFDM9	15
131ceaec73dSDamien Bergamini #define IWI_RATE_OFDM12	5
132ceaec73dSDamien Bergamini #define IWI_RATE_OFDM18	7
133ceaec73dSDamien Bergamini #define IWI_RATE_OFDM24	9
134ceaec73dSDamien Bergamini #define IWI_RATE_OFDM36	11
135ceaec73dSDamien Bergamini #define IWI_RATE_OFDM48	1
136ceaec73dSDamien Bergamini #define IWI_RATE_OFDM54	3
137ceaec73dSDamien Bergamini 
138b8c4cc42SLuigi Rizzo /*
139b8c4cc42SLuigi Rizzo  * Old version firmware images start with this header,
140b8c4cc42SLuigi Rizzo  * fields are in little endian (le32) format.
141b8c4cc42SLuigi Rizzo  */
142c10b1400SMax Laier struct iwi_firmware_ohdr {
143408146edSDamien Bergamini 	uint32_t	version;
144c10b1400SMax Laier 	uint32_t	mode;
145c10b1400SMax Laier };
146c10b1400SMax Laier #define	IWI_FW_REQ_MAJOR	2
147c10b1400SMax Laier #define	IWI_FW_REQ_MINOR	4
148c10b1400SMax Laier #define	IWI_FW_GET_MAJOR(ver)	((ver) & 0xff)
149c10b1400SMax Laier #define	IWI_FW_GET_MINOR(ver)	(((ver) & 0xff00) >> 8)
150c10b1400SMax Laier 
151c10b1400SMax Laier #define	IWI_FW_MODE_UCODE	0
152c10b1400SMax Laier #define	IWI_FW_MODE_BOOT	0
153c10b1400SMax Laier #define	IWI_FW_MODE_BSS		0
154c10b1400SMax Laier #define	IWI_FW_MODE_IBSS	1
155c10b1400SMax Laier #define	IWI_FW_MODE_MONITOR	2
156c10b1400SMax Laier 
157b8c4cc42SLuigi Rizzo /*
158b8c4cc42SLuigi Rizzo  * New version firmware images contain boot, ucode and firmware
159b8c4cc42SLuigi Rizzo  * all in one chunk. The header at the beginning gives the version
160b8c4cc42SLuigi Rizzo  * and the size of each (sub)image, in le32 format.
161b8c4cc42SLuigi Rizzo  */
162c10b1400SMax Laier struct iwi_firmware_hdr {
163c10b1400SMax Laier 	uint32_t	version;	/* version stamp */
164c10b1400SMax Laier 	uint32_t	bsize;		/* size of boot image */
165c10b1400SMax Laier 	uint32_t	usize;		/* size of ucode image */
166c10b1400SMax Laier 	uint32_t	fsize;		/* size of firmware image */
167c10b1400SMax Laier };
168408146edSDamien Bergamini 
169ceaec73dSDamien Bergamini struct iwi_hdr {
170ceaec73dSDamien Bergamini 	uint8_t	type;
171ceaec73dSDamien Bergamini #define IWI_HDR_TYPE_DATA	0
172ceaec73dSDamien Bergamini #define IWI_HDR_TYPE_COMMAND	1
173ceaec73dSDamien Bergamini #define IWI_HDR_TYPE_NOTIF	3
174ceaec73dSDamien Bergamini #define IWI_HDR_TYPE_FRAME	9
175ceaec73dSDamien Bergamini 
176ceaec73dSDamien Bergamini 	uint8_t	seq;
177ceaec73dSDamien Bergamini 	uint8_t	flags;
178ceaec73dSDamien Bergamini #define IWI_HDR_FLAG_IRQ	0x04
179ceaec73dSDamien Bergamini 
180ceaec73dSDamien Bergamini 	uint8_t	reserved;
181ceaec73dSDamien Bergamini } __packed;
182ceaec73dSDamien Bergamini 
183ceaec73dSDamien Bergamini struct iwi_notif {
184ceaec73dSDamien Bergamini 	uint32_t	reserved[2];
185ceaec73dSDamien Bergamini 	uint8_t		type;
186c10b1400SMax Laier #define IWI_NOTIF_TYPE_SUCCESS		0
187c10b1400SMax Laier #define IWI_NOTIF_TYPE_UNSPECIFIED	1	/* unspecified failure */
188ceaec73dSDamien Bergamini #define IWI_NOTIF_TYPE_ASSOCIATION	10
189ceaec73dSDamien Bergamini #define IWI_NOTIF_TYPE_AUTHENTICATION	11
190ceaec73dSDamien Bergamini #define IWI_NOTIF_TYPE_SCAN_CHANNEL	12
191ceaec73dSDamien Bergamini #define IWI_NOTIF_TYPE_SCAN_COMPLETE	13
192c10b1400SMax Laier #define IWI_NOTIF_TYPE_FRAG_LENGTH	14
193c10b1400SMax Laier #define IWI_NOTIF_TYPE_LINK_QUALITY	15	/* "link deterioration" */
194c10b1400SMax Laier #define IWI_NOTIF_TYPE_BEACON		17	/* beacon state, e.g. miss */
195c10b1400SMax Laier #define	IWI_NOTIF_TYPE_TGI_TX_KEY	18	/* WPA transmit key */
196ceaec73dSDamien Bergamini #define IWI_NOTIF_TYPE_CALIBRATION	20
197ceaec73dSDamien Bergamini #define IWI_NOTIF_TYPE_NOISE		25
198ceaec73dSDamien Bergamini 
199ceaec73dSDamien Bergamini 	uint8_t		flags;
200ceaec73dSDamien Bergamini 	uint16_t	len;
201ceaec73dSDamien Bergamini } __packed;
202ceaec73dSDamien Bergamini 
203ceaec73dSDamien Bergamini /* structure for notification IWI_NOTIF_TYPE_AUTHENTICATION */
204ceaec73dSDamien Bergamini struct iwi_notif_authentication {
205ceaec73dSDamien Bergamini 	uint8_t	state;
206c10b1400SMax Laier #define IWI_AUTH_FAIL		0
207c10b1400SMax Laier #define	IWI_AUTH_SENT_1		1		/* tx first frame */
208c10b1400SMax Laier #define	IWI_AUTH_RECV_2		2		/* rx second frame */
209c10b1400SMax Laier #define	IWI_AUTH_SEQ1_PASS	3		/* 1st exchange passed */
210c10b1400SMax Laier #define	IWI_AUTH_SEQ1_FAIL	4		/* 1st exchange failed */
211c10b1400SMax Laier #define IWI_AUTH_SUCCESS	9
212ceaec73dSDamien Bergamini } __packed;
213ceaec73dSDamien Bergamini 
214ceaec73dSDamien Bergamini /* structure for notification IWI_NOTIF_TYPE_ASSOCIATION */
215ceaec73dSDamien Bergamini struct iwi_notif_association {
216ceaec73dSDamien Bergamini 	uint8_t			state;
21768e8e04eSSam Leffler #define IWI_ASSOC_INIT		0
218c10b1400SMax Laier #define IWI_ASSOC_SUCCESS	12
219c10b1400SMax Laier 	uint8_t			pad[11];
220ceaec73dSDamien Bergamini } __packed;
221ceaec73dSDamien Bergamini 
222ceaec73dSDamien Bergamini /* structure for notification IWI_NOTIF_TYPE_SCAN_CHANNEL */
223ceaec73dSDamien Bergamini struct iwi_notif_scan_channel {
224ceaec73dSDamien Bergamini 	uint8_t	nchan;
2254982d693SAdrian Chadd 	/* XXX this is iwi_cmd_stats, and a u8 reserved field */
226ceaec73dSDamien Bergamini 	uint8_t	reserved[47];
227ceaec73dSDamien Bergamini } __packed;
228ceaec73dSDamien Bergamini 
229ceaec73dSDamien Bergamini /* structure for notification IWI_NOTIF_TYPE_SCAN_COMPLETE */
230ceaec73dSDamien Bergamini struct iwi_notif_scan_complete {
231ceaec73dSDamien Bergamini 	uint8_t	type;
232ceaec73dSDamien Bergamini 	uint8_t	nchan;
233ceaec73dSDamien Bergamini 	uint8_t	status;
234ceaec73dSDamien Bergamini 	uint8_t	reserved;
235ceaec73dSDamien Bergamini } __packed;
236ceaec73dSDamien Bergamini 
237c10b1400SMax Laier /* structure for notification IWI_NOTIF_TYPE_BEACON */
238c10b1400SMax Laier struct iwi_notif_beacon_state {
239c10b1400SMax Laier 	uint32_t state;
240c10b1400SMax Laier #define IWI_BEACON_MISS		1
241c10b1400SMax Laier 	uint32_t number;
242c10b1400SMax Laier } __packed;
243c10b1400SMax Laier 
2444982d693SAdrian Chadd /* structure(s) for notification IWI_NOTIF_TYPE_LINK_QUALITY */
2454982d693SAdrian Chadd 
2464982d693SAdrian Chadd #define RX_FREE_BUFFERS 32
2474982d693SAdrian Chadd #define RX_LOW_WATERMARK 8
2484982d693SAdrian Chadd 
2494982d693SAdrian Chadd #define SUP_RATE_11A_MAX_NUM_CHANNELS  8
2504982d693SAdrian Chadd #define SUP_RATE_11B_MAX_NUM_CHANNELS  4
2514982d693SAdrian Chadd #define SUP_RATE_11G_MAX_NUM_CHANNELS  12
2524982d693SAdrian Chadd 
2534982d693SAdrian Chadd // Used for passing to driver number of successes and failures per rate
2544982d693SAdrian Chadd struct iwi_rate_histogram {
2554982d693SAdrian Chadd         union {
2564982d693SAdrian Chadd                 uint32_t a[SUP_RATE_11A_MAX_NUM_CHANNELS];
2574982d693SAdrian Chadd                 uint32_t b[SUP_RATE_11B_MAX_NUM_CHANNELS];
2584982d693SAdrian Chadd                 uint32_t g[SUP_RATE_11G_MAX_NUM_CHANNELS];
2594982d693SAdrian Chadd         } success;
2604982d693SAdrian Chadd         union {
2614982d693SAdrian Chadd                 uint32_t a[SUP_RATE_11A_MAX_NUM_CHANNELS];
2624982d693SAdrian Chadd                 uint32_t b[SUP_RATE_11B_MAX_NUM_CHANNELS];
2634982d693SAdrian Chadd                 uint32_t g[SUP_RATE_11G_MAX_NUM_CHANNELS];
2644982d693SAdrian Chadd         } failed;
2654982d693SAdrian Chadd } __packed;
2664982d693SAdrian Chadd 
2674982d693SAdrian Chadd /* statistics command response */
2684982d693SAdrian Chadd struct iwi_cmd_stats {
2694982d693SAdrian Chadd 	uint8_t cmd_id;
2704982d693SAdrian Chadd 	uint8_t seq_num;
2714982d693SAdrian Chadd 	uint16_t good_sfd;
2724982d693SAdrian Chadd 	uint16_t bad_plcp;
2734982d693SAdrian Chadd 	uint16_t wrong_bssid;
2744982d693SAdrian Chadd 	uint16_t valid_mpdu;
2754982d693SAdrian Chadd 	uint16_t bad_mac_header;
2764982d693SAdrian Chadd 	uint16_t reserved_frame_types;
2774982d693SAdrian Chadd 	uint16_t rx_ina;
2784982d693SAdrian Chadd 	uint16_t bad_crc32;
2794982d693SAdrian Chadd 	uint16_t invalid_cts;
2804982d693SAdrian Chadd 	uint16_t invalid_acks;
2814982d693SAdrian Chadd 	uint16_t long_distance_ina_fina;
2824982d693SAdrian Chadd 	uint16_t dsp_silence_unreachable;
2834982d693SAdrian Chadd 	uint16_t accumulated_rssi;
2844982d693SAdrian Chadd 	uint16_t rx_ovfl_frame_tossed;
2854982d693SAdrian Chadd 	uint16_t rssi_silence_threshold;
2864982d693SAdrian Chadd 	uint16_t rx_ovfl_frame_supplied;
2874982d693SAdrian Chadd 	uint16_t last_rx_frame_signal;
2884982d693SAdrian Chadd 	uint16_t last_rx_frame_noise;
2894982d693SAdrian Chadd 	uint16_t rx_autodetec_no_ofdm;
2904982d693SAdrian Chadd 	uint16_t rx_autodetec_no_barker;
2914982d693SAdrian Chadd 	uint16_t reserved;
2924982d693SAdrian Chadd } __packed;
2934982d693SAdrian Chadd 
2944982d693SAdrian Chadd #define	SILENCE_OVER_THRESH		(1)
2954982d693SAdrian Chadd #define	SILENCE_UNDER_THRESH		(2)
2964982d693SAdrian Chadd 
2974982d693SAdrian Chadd struct iwi_notif_link_quality {
2984982d693SAdrian Chadd 	struct iwi_cmd_stats stats;
2994982d693SAdrian Chadd 	uint8_t rate;
3004982d693SAdrian Chadd 	uint8_t modulation;
3014982d693SAdrian Chadd 	struct iwi_rate_histogram histogram;
3024982d693SAdrian Chadd 	uint8_t silence_notification_type;   /* SILENCE_OVER/UNDER_THRESH */
3034982d693SAdrian Chadd 	uint16_t silence_count;
3044982d693SAdrian Chadd } __packed;
3054982d693SAdrian Chadd 
306ceaec73dSDamien Bergamini /* received frame header */
307ceaec73dSDamien Bergamini struct iwi_frame {
308ceaec73dSDamien Bergamini 	uint32_t	reserved1[2];
309ceaec73dSDamien Bergamini 	uint8_t		chan;
310ceaec73dSDamien Bergamini 	uint8_t		status;
311ceaec73dSDamien Bergamini 	uint8_t		rate;
312ceaec73dSDamien Bergamini 	uint8_t		rssi;
313ceaec73dSDamien Bergamini 	uint8_t		agc;
314ceaec73dSDamien Bergamini 	uint8_t		rssi_dbm;
315ceaec73dSDamien Bergamini 	uint16_t	signal;
316ceaec73dSDamien Bergamini 	uint16_t	noise;
317ceaec73dSDamien Bergamini 	uint8_t		antenna;
318ceaec73dSDamien Bergamini 	uint8_t		control;
319ceaec73dSDamien Bergamini 	uint8_t		reserved2[2];
320ceaec73dSDamien Bergamini 	uint16_t	len;
321ceaec73dSDamien Bergamini } __packed;
322ceaec73dSDamien Bergamini 
323ceaec73dSDamien Bergamini /* header for transmission */
324ceaec73dSDamien Bergamini struct iwi_tx_desc {
325ceaec73dSDamien Bergamini 	struct iwi_hdr	hdr;
326ceaec73dSDamien Bergamini 	uint32_t	reserved1;
327c10b1400SMax Laier 	uint8_t		station;	/* adhoc sta #, 0 for bss */
328ceaec73dSDamien Bergamini 	uint8_t		reserved2[3];
329ceaec73dSDamien Bergamini 	uint8_t		cmd;
330ceaec73dSDamien Bergamini #define IWI_DATA_CMD_TX	0x0b
331ceaec73dSDamien Bergamini 
332ceaec73dSDamien Bergamini 	uint8_t		seq;
333ceaec73dSDamien Bergamini 	uint16_t	len;
334ceaec73dSDamien Bergamini 	uint8_t		priority;
335ceaec73dSDamien Bergamini 	uint8_t		flags;
336ceaec73dSDamien Bergamini #define IWI_DATA_FLAG_SHPREAMBLE	0x04
337ceaec73dSDamien Bergamini #define IWI_DATA_FLAG_NO_WEP		0x20
338ceaec73dSDamien Bergamini #define IWI_DATA_FLAG_NEED_ACK		0x80
339ceaec73dSDamien Bergamini 
340ceaec73dSDamien Bergamini 	uint8_t		xflags;
341ec01dc2bSDamien Bergamini #define IWI_DATA_XFLAG_QOS	0x10
342ec01dc2bSDamien Bergamini 
343c10b1400SMax Laier 	uint8_t		wep_txkey;
344ceaec73dSDamien Bergamini 	uint8_t		wepkey[IEEE80211_KEYBUF_SIZE];
345ceaec73dSDamien Bergamini 	uint8_t		rate;
346ceaec73dSDamien Bergamini 	uint8_t		antenna;
347ceaec73dSDamien Bergamini 	uint8_t		reserved3[10];
348ceaec73dSDamien Bergamini 	struct ieee80211_qosframe_addr4	wh;
349ceaec73dSDamien Bergamini 	uint32_t	iv;
350ceaec73dSDamien Bergamini 	uint32_t	eiv;
351c10b1400SMax Laier 
352ceaec73dSDamien Bergamini 	uint32_t	nseg;
353ceaec73dSDamien Bergamini #define IWI_MAX_NSEG	6
354ceaec73dSDamien Bergamini 	uint32_t	seg_addr[IWI_MAX_NSEG];
355ceaec73dSDamien Bergamini 	uint16_t	seg_len[IWI_MAX_NSEG];
356ceaec73dSDamien Bergamini } __packed;
357ceaec73dSDamien Bergamini 
358ceaec73dSDamien Bergamini /* command */
359ceaec73dSDamien Bergamini struct iwi_cmd_desc {
360ceaec73dSDamien Bergamini 	struct iwi_hdr	hdr;
361ceaec73dSDamien Bergamini 	uint8_t		type;
362ceaec73dSDamien Bergamini #define IWI_CMD_ENABLE				2
363ceaec73dSDamien Bergamini #define IWI_CMD_SET_CONFIG			6
364ceaec73dSDamien Bergamini #define IWI_CMD_SET_ESSID			8
365ceaec73dSDamien Bergamini #define IWI_CMD_SET_MAC_ADDRESS			11
366ceaec73dSDamien Bergamini #define IWI_CMD_SET_RTS_THRESHOLD		15
367acea4241SDamien Bergamini #define IWI_CMD_SET_FRAG_THRESHOLD		16
368ceaec73dSDamien Bergamini #define IWI_CMD_SET_POWER_MODE			17
369ceaec73dSDamien Bergamini #define IWI_CMD_SET_WEP_KEY			18
370c10b1400SMax Laier #define IWI_CMD_SCAN				20
371ceaec73dSDamien Bergamini #define IWI_CMD_ASSOCIATE			21
372ceaec73dSDamien Bergamini #define IWI_CMD_SET_RATES			22
373acea4241SDamien Bergamini #define IWI_CMD_ABORT_SCAN			23
374ec01dc2bSDamien Bergamini #define IWI_CMD_SET_WME_PARAMS			25
375c10b1400SMax Laier #define IWI_CMD_SCAN_EXT			26
376acea4241SDamien Bergamini #define IWI_CMD_SET_OPTIE			31
377ceaec73dSDamien Bergamini #define IWI_CMD_DISABLE				33
378ceaec73dSDamien Bergamini #define IWI_CMD_SET_IV				34
379ceaec73dSDamien Bergamini #define IWI_CMD_SET_TX_POWER			35
380ceaec73dSDamien Bergamini #define IWI_CMD_SET_SENSITIVITY			42
381ec01dc2bSDamien Bergamini #define IWI_CMD_SET_WMEIE			84
382ceaec73dSDamien Bergamini 
383ceaec73dSDamien Bergamini 	uint8_t		len;
384ceaec73dSDamien Bergamini 	uint16_t	reserved;
385ceaec73dSDamien Bergamini 	uint8_t		data[120];
386ceaec73dSDamien Bergamini } __packed;
387ceaec73dSDamien Bergamini 
3880b74a285SDamien Bergamini /* node information (IBSS) */
38928a38073SDamien Bergamini struct iwi_ibssnode {
3900b74a285SDamien Bergamini 	uint8_t	bssid[IEEE80211_ADDR_LEN];
3910b74a285SDamien Bergamini 	uint8_t	reserved[2];
3920b74a285SDamien Bergamini } __packed;
3930b74a285SDamien Bergamini 
394ceaec73dSDamien Bergamini /* constants for 'mode' fields */
395ceaec73dSDamien Bergamini #define IWI_MODE_11A	0
396ceaec73dSDamien Bergamini #define IWI_MODE_11B	1
397ceaec73dSDamien Bergamini #define IWI_MODE_11G	2
398ceaec73dSDamien Bergamini 
399ceaec73dSDamien Bergamini /* possible values for command IWI_CMD_SET_POWER_MODE */
400c10b1400SMax Laier #define IWI_POWER_MODE_CAM	0	/* no power save */
401c10b1400SMax Laier #define IWI_POWER_MODE_PSP	3
402c10b1400SMax Laier #define IWI_POWER_MODE_MAX	5	/* max power save operation */
403ceaec73dSDamien Bergamini 
404ceaec73dSDamien Bergamini /* structure for command IWI_CMD_SET_RATES */
405ceaec73dSDamien Bergamini struct iwi_rateset {
406ceaec73dSDamien Bergamini 	uint8_t	mode;
407ceaec73dSDamien Bergamini 	uint8_t	nrates;
408ceaec73dSDamien Bergamini 	uint8_t	type;
40980e1a712SDamien Bergamini #define IWI_RATESET_TYPE_NEGOTIATED	0
410ceaec73dSDamien Bergamini #define IWI_RATESET_TYPE_SUPPORTED	1
411ceaec73dSDamien Bergamini 
412ceaec73dSDamien Bergamini 	uint8_t	reserved;
413aaae09daSMax Laier #define	IWI_RATESET_SIZE	12
414aaae09daSMax Laier 	uint8_t	rates[IWI_RATESET_SIZE];
415ceaec73dSDamien Bergamini } __packed;
416ceaec73dSDamien Bergamini 
417ceaec73dSDamien Bergamini /* structure for command IWI_CMD_SET_TX_POWER */
418ceaec73dSDamien Bergamini struct iwi_txpower {
419ceaec73dSDamien Bergamini 	uint8_t	nchan;
420ceaec73dSDamien Bergamini 	uint8_t	mode;
421ceaec73dSDamien Bergamini 	struct {
422ceaec73dSDamien Bergamini 		uint8_t	chan;
423ceaec73dSDamien Bergamini 		uint8_t	power;
424ceaec73dSDamien Bergamini #define IWI_TXPOWER_MAX		20
425ceaec73dSDamien Bergamini #define IWI_TXPOWER_RATIO	(IEEE80211_TXPOWER_MAX / IWI_TXPOWER_MAX)
426ceaec73dSDamien Bergamini 	} __packed chan[37];
427ceaec73dSDamien Bergamini } __packed;
428ceaec73dSDamien Bergamini 
429ceaec73dSDamien Bergamini /* structure for command IWI_CMD_ASSOCIATE */
430ceaec73dSDamien Bergamini struct iwi_associate {
431c10b1400SMax Laier 	uint8_t		chan;		/* channel # */
432c10b1400SMax Laier 	uint8_t		auth;		/* type and key */
433ceaec73dSDamien Bergamini #define IWI_AUTH_OPEN	0
434ceaec73dSDamien Bergamini #define IWI_AUTH_SHARED	1
435ceaec73dSDamien Bergamini #define IWI_AUTH_NONE	3
436ceaec73dSDamien Bergamini 
437c10b1400SMax Laier 	uint8_t		type;		/* request */
438c10b1400SMax Laier #define	IWI_HC_ASSOC		0
439c10b1400SMax Laier #define	IWI_HC_REASSOC		1
440c10b1400SMax Laier #define	IWI_HC_DISASSOC		2
441c10b1400SMax Laier #define	IWI_HC_IBSS_START	3
442c10b1400SMax Laier #define	IWI_HC_IBSS_RECONF	4
443c10b1400SMax Laier #define	IWI_HC_DISASSOC_QUIET	5
444c10b1400SMax Laier 	uint8_t		reserved;
445acea4241SDamien Bergamini 	uint16_t	policy;
446ec01dc2bSDamien Bergamini #define IWI_POLICY_WME	1
447ec01dc2bSDamien Bergamini #define IWI_POLICY_WPA	2
448acea4241SDamien Bergamini 
449c10b1400SMax Laier 	uint8_t		plen;		/* preamble length */
450c10b1400SMax Laier 	uint8_t		mode;		/* 11a, 11b, or 11g */
451ceaec73dSDamien Bergamini 	uint8_t		bssid[IEEE80211_ADDR_LEN];
452c10b1400SMax Laier 	uint8_t		tstamp[8];	/* tsf for beacon sync */
453ceaec73dSDamien Bergamini 	uint16_t	capinfo;
454c10b1400SMax Laier 	uint16_t	lintval;	/* listen interval */
455c10b1400SMax Laier 	uint16_t	intval;		/* beacon interval */
456ceaec73dSDamien Bergamini 	uint8_t		dst[IEEE80211_ADDR_LEN];
457c10b1400SMax Laier 	uint16_t	atim_window;
458c10b1400SMax Laier 	uint8_t		smr;
459c10b1400SMax Laier 	uint8_t		reserved1;
460c10b1400SMax Laier 	uint16_t	reserved2;
461ceaec73dSDamien Bergamini } __packed;
462ceaec73dSDamien Bergamini 
463c10b1400SMax Laier #define	IWI_SCAN_CHANNELS	54
464c10b1400SMax Laier 
465ceaec73dSDamien Bergamini /* structure for command IWI_CMD_SCAN */
466ceaec73dSDamien Bergamini struct iwi_scan {
467c10b1400SMax Laier 	uint8_t		type;
468c10b1400SMax Laier 	uint16_t	dwelltime;	/* channel dwell time (ms) */
469c10b1400SMax Laier 	uint8_t		channels[IWI_SCAN_CHANNELS];
470ceaec73dSDamien Bergamini #define IWI_CHAN_5GHZ	(0 << 6)
471ceaec73dSDamien Bergamini #define IWI_CHAN_2GHZ	(1 << 6)
472ceaec73dSDamien Bergamini 
473c10b1400SMax Laier 	uint8_t		reserved[3];
474c10b1400SMax Laier } __packed;
47580e1a712SDamien Bergamini 
476c10b1400SMax Laier /* scan type codes */
477c10b1400SMax Laier #define IWI_SCAN_TYPE_PASSIVE_STOP	0 /* passive, stop on first beacon */
478c10b1400SMax Laier #define IWI_SCAN_TYPE_PASSIVE		1 /* passive, full dwell on channel */
479c10b1400SMax Laier #define IWI_SCAN_TYPE_DIRECTED		2 /* active, directed probe req */
480c10b1400SMax Laier #define IWI_SCAN_TYPE_BROADCAST		3 /* active, bcast probe req */
481c10b1400SMax Laier #define IWI_SCAN_TYPE_BDIRECTED		4 /* active, directed+bcast probe */
482c10b1400SMax Laier #define IWI_SCAN_TYPES			5
483c10b1400SMax Laier 
48468e8e04eSSam Leffler /* scan result codes */
485453130d9SPedro F. Giffuni #define	IWI_SCAN_COMPLETED		1 /* scan compeleted successfully */
48668e8e04eSSam Leffler #define IWI_SCAN_ABORTED		2 /* scan was aborted by the driver */
48768e8e04eSSam Leffler 
488c10b1400SMax Laier /* structure for command IWI_CMD_SCAN_EXT */
489c10b1400SMax Laier struct iwi_scan_ext {
490c10b1400SMax Laier 	uint32_t	full_scan_index;
491c10b1400SMax Laier 	uint8_t		channels[IWI_SCAN_CHANNELS];
492c10b1400SMax Laier 	uint8_t		scan_type[IWI_SCAN_CHANNELS / 2];
493c10b1400SMax Laier 	uint8_t		reserved;
494c10b1400SMax Laier 	uint16_t	dwell_time[IWI_SCAN_TYPES];
495ceaec73dSDamien Bergamini } __packed;
496ceaec73dSDamien Bergamini 
497ceaec73dSDamien Bergamini /* structure for command IWI_CMD_SET_CONFIG */
498ceaec73dSDamien Bergamini struct iwi_configuration {
499ceaec73dSDamien Bergamini 	uint8_t	bluetooth_coexistence;
500ceaec73dSDamien Bergamini 	uint8_t	reserved1;
501c10b1400SMax Laier 	uint8_t	answer_pbreq;		/* answer bcast ssid probe req frames */
502c10b1400SMax Laier 	uint8_t	allow_invalid_frames;	/* accept data frames w/ errors */
503c10b1400SMax Laier 	uint8_t	multicast_enabled;	/* accept frames w/ any bssid */
504acea4241SDamien Bergamini 	uint8_t	drop_unicast_unencrypted;
505ceaec73dSDamien Bergamini 	uint8_t	disable_unicast_decryption;
506acea4241SDamien Bergamini 	uint8_t	drop_multicast_unencrypted;
507ceaec73dSDamien Bergamini 	uint8_t	disable_multicast_decryption;
508c10b1400SMax Laier 	uint8_t	antenna;		/* antenna diversity */
509c10b1400SMax Laier #define	IWI_ANTENNA_AUTO	0	/* firmware selects best antenna */
510c10b1400SMax Laier #define	IWI_ANTENNA_A		1	/* use antenna A only */
511c10b1400SMax Laier #define	IWI_ANTENNA_B		3	/* use antenna B only */
512c10b1400SMax Laier #define	IWI_ANTENNA_SLOWDIV	2	/* slow diversity algorithm */
513c10b1400SMax Laier 	uint8_t	include_crc;		/* include crc in rx'd frames */
514c10b1400SMax Laier 	uint8_t	use_protection;		/* auto-detect 11g operation */
515c10b1400SMax Laier 	uint8_t	protection_ctsonly;	/* use CTS-to-self protection */
516ceaec73dSDamien Bergamini 	uint8_t	enable_multicast_filtering;
517c10b1400SMax Laier 	uint8_t	bluetooth_threshold;	/* collision threshold */
518c10b1400SMax Laier 	uint8_t	silence_threshold;	/* silence over/under threshold */
519c10b1400SMax Laier 	uint8_t	allow_beacon_and_probe_resp;/* accept frames w/ any bssid */
520c10b1400SMax Laier 	uint8_t	allow_mgt;		/* accept frames w/ any bssid */
521c10b1400SMax Laier 	uint8_t	noise_reported;		/* report noise stats to host */
522ceaec73dSDamien Bergamini 	uint8_t	reserved5;
523ceaec73dSDamien Bergamini } __packed;
524ceaec73dSDamien Bergamini 
525ceaec73dSDamien Bergamini /* structure for command IWI_CMD_SET_WEP_KEY */
526ceaec73dSDamien Bergamini struct iwi_wep_key {
527ceaec73dSDamien Bergamini 	uint8_t	cmd;
528ceaec73dSDamien Bergamini #define IWI_WEP_KEY_CMD_SETKEY	0x08
529ceaec73dSDamien Bergamini 
530ceaec73dSDamien Bergamini 	uint8_t	seq;
531ceaec73dSDamien Bergamini 	uint8_t	idx;
532ceaec73dSDamien Bergamini 	uint8_t	len;
533ceaec73dSDamien Bergamini 	uint8_t	key[IEEE80211_KEYBUF_SIZE];
534ceaec73dSDamien Bergamini } __packed;
535ceaec73dSDamien Bergamini 
536ec01dc2bSDamien Bergamini /* structure for command IWI_CMD_SET_WME_PARAMS */
537ec01dc2bSDamien Bergamini struct iwi_wme_params {
538fb533d55SDamien Bergamini 	uint16_t	cwmin[WME_NUM_AC];
539fb533d55SDamien Bergamini 	uint16_t	cwmax[WME_NUM_AC];
540ec01dc2bSDamien Bergamini 	uint8_t		aifsn[WME_NUM_AC];
541ec01dc2bSDamien Bergamini 	uint8_t		acm[WME_NUM_AC];
542fb533d55SDamien Bergamini 	uint16_t	burst[WME_NUM_AC];
543ec01dc2bSDamien Bergamini } __packed;
544ec01dc2bSDamien Bergamini 
545c10b1400SMax Laier /* structure for command IWI_CMD_SET_SENSITIVTY */
546c10b1400SMax Laier struct iwi_sensitivity {
547c10b1400SMax Laier 	uint16_t rssi;			/* beacon rssi in dBm */
548c10b1400SMax Laier #define	IWI_RSSI_TO_DBM		112
549c10b1400SMax Laier 	uint16_t reserved;
550c10b1400SMax Laier } __packed;
551c10b1400SMax Laier 
552c10b1400SMax Laier #define IWI_MEM_EEPROM_EVENT	0x00300004
553ceaec73dSDamien Bergamini #define IWI_MEM_EEPROM_CTL	0x00300040
554ceaec73dSDamien Bergamini 
555ceaec73dSDamien Bergamini #define IWI_EEPROM_MAC	0x21
556c10b1400SMax Laier #define IWI_EEPROM_NIC	0x25		/* nic type (lsb) */
557c10b1400SMax Laier #define IWI_EEPROM_SKU	0x25		/* nic type (msb) */
558ceaec73dSDamien Bergamini 
559ceaec73dSDamien Bergamini #define IWI_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
560ceaec73dSDamien Bergamini 
561ceaec73dSDamien Bergamini #define IWI_EEPROM_C	(1 << 0)	/* Serial Clock */
562ceaec73dSDamien Bergamini #define IWI_EEPROM_S	(1 << 1)	/* Chip Select */
563ceaec73dSDamien Bergamini #define IWI_EEPROM_D	(1 << 2)	/* Serial data input */
564ceaec73dSDamien Bergamini #define IWI_EEPROM_Q	(1 << 4)	/* Serial data output */
565ceaec73dSDamien Bergamini 
566ceaec73dSDamien Bergamini #define IWI_EEPROM_SHIFT_D    2
567ceaec73dSDamien Bergamini #define IWI_EEPROM_SHIFT_Q    4
568ceaec73dSDamien Bergamini 
569ceaec73dSDamien Bergamini /*
570ceaec73dSDamien Bergamini  * control and status registers access macros
571ceaec73dSDamien Bergamini  */
572ceaec73dSDamien Bergamini #define CSR_READ_1(sc, reg)						\
573ceaec73dSDamien Bergamini 	bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
574ceaec73dSDamien Bergamini 
575ceaec73dSDamien Bergamini #define CSR_READ_2(sc, reg)						\
576ceaec73dSDamien Bergamini 	bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))
577ceaec73dSDamien Bergamini 
578ceaec73dSDamien Bergamini #define CSR_READ_4(sc, reg)						\
579ceaec73dSDamien Bergamini 	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
580ceaec73dSDamien Bergamini 
581ceaec73dSDamien Bergamini #define CSR_READ_REGION_4(sc, offset, datap, count)			\
582ceaec73dSDamien Bergamini 	bus_space_read_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
583ceaec73dSDamien Bergamini 	    (datap), (count))
584ceaec73dSDamien Bergamini 
585ceaec73dSDamien Bergamini #define CSR_WRITE_1(sc, reg, val)					\
586ceaec73dSDamien Bergamini 	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
587ceaec73dSDamien Bergamini 
588ceaec73dSDamien Bergamini #define CSR_WRITE_2(sc, reg, val)					\
589ceaec73dSDamien Bergamini 	bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
590ceaec73dSDamien Bergamini 
591ceaec73dSDamien Bergamini #define CSR_WRITE_4(sc, reg, val)					\
592ceaec73dSDamien Bergamini 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
593ceaec73dSDamien Bergamini 
5940b74a285SDamien Bergamini #define CSR_WRITE_REGION_1(sc, offset, datap, count)			\
5950b74a285SDamien Bergamini 	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
5960b74a285SDamien Bergamini 	    (datap), (count))
5970b74a285SDamien Bergamini 
598ceaec73dSDamien Bergamini /*
599ceaec73dSDamien Bergamini  * indirect memory space access macros
600ceaec73dSDamien Bergamini  */
601ceaec73dSDamien Bergamini #define MEM_WRITE_1(sc, addr, val) do {					\
602ceaec73dSDamien Bergamini 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
603ceaec73dSDamien Bergamini 	CSR_WRITE_1((sc), IWI_CSR_INDIRECT_DATA, (val));		\
604ceaec73dSDamien Bergamini } while (/* CONSTCOND */0)
605ceaec73dSDamien Bergamini 
606ceaec73dSDamien Bergamini #define MEM_WRITE_2(sc, addr, val) do {					\
607ceaec73dSDamien Bergamini 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
608ceaec73dSDamien Bergamini 	CSR_WRITE_2((sc), IWI_CSR_INDIRECT_DATA, (val));		\
609ceaec73dSDamien Bergamini } while (/* CONSTCOND */0)
610ceaec73dSDamien Bergamini 
611ceaec73dSDamien Bergamini #define MEM_WRITE_4(sc, addr, val) do {					\
612ceaec73dSDamien Bergamini 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
613ceaec73dSDamien Bergamini 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_DATA, (val));		\
614ceaec73dSDamien Bergamini } while (/* CONSTCOND */0)
615ceaec73dSDamien Bergamini 
616ceaec73dSDamien Bergamini #define MEM_WRITE_MULTI_1(sc, addr, buf, len) do {			\
617ceaec73dSDamien Bergamini 	CSR_WRITE_4((sc), IWI_CSR_INDIRECT_ADDR, (addr));		\
618ceaec73dSDamien Bergamini 	CSR_WRITE_MULTI_1((sc), IWI_CSR_INDIRECT_DATA, (buf), (len));	\
619ceaec73dSDamien Bergamini } while (/* CONSTCOND */0)
620ceaec73dSDamien Bergamini 
621ceaec73dSDamien Bergamini /*
622ceaec73dSDamien Bergamini  * EEPROM access macro
623ceaec73dSDamien Bergamini  */
624ceaec73dSDamien Bergamini #define IWI_EEPROM_CTL(sc, val) do {					\
625ceaec73dSDamien Bergamini 	MEM_WRITE_4((sc), IWI_MEM_EEPROM_CTL, (val));			\
626ceaec73dSDamien Bergamini 	DELAY(IWI_EEPROM_DELAY);					\
627ceaec73dSDamien Bergamini } while (/* CONSTCOND */0)
628