1 | /* $NetBSD: if_ipwreg.h,v 1.6 2007/12/25 18:33:40 perry Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2004, 2005 |
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 IPW_NTBD 128 |
31 | #define IPW_TBD_SZ (IPW_NTBD * sizeof (struct ipw_bd)) |
32 | #define IPW_NDATA (IPW_NTBD / 2) |
33 | #define IPW_HDR_SZ (IPW_NDATA * sizeof (struct ipw_soft_hdr)) |
34 | #define IPW_NRBD 128 |
35 | #define IPW_RBD_SZ (IPW_NRBD * sizeof (struct ipw_bd)) |
36 | #define IPW_STATUS_SZ (IPW_NRBD * sizeof (struct ipw_status)) |
37 | |
38 | #define IPW_CSR_INTR 0x0008 |
39 | #define IPW_CSR_INTR_MASK 0x000c |
40 | #define IPW_CSR_INDIRECT_ADDR 0x0010 |
41 | #define IPW_CSR_INDIRECT_DATA 0x0014 |
42 | #define IPW_CSR_AUTOINC_ADDR 0x0018 |
43 | #define IPW_CSR_AUTOINC_DATA 0x001c |
44 | #define IPW_CSR_RST 0x0020 |
45 | #define IPW_CSR_CTL 0x0024 |
46 | #define IPW_CSR_IO 0x0030 |
47 | #define IPW_CSR_TX_BASE 0x0200 |
48 | #define IPW_CSR_TX_SIZE 0x0204 |
49 | #define IPW_CSR_RX_BASE 0x0240 |
50 | #define IPW_CSR_STATUS_BASE 0x0244 |
51 | #define IPW_CSR_RX_SIZE 0x0248 |
52 | #define IPW_CSR_TX_READ 0x0280 |
53 | #define IPW_CSR_RX_READ 0x02a0 |
54 | #define IPW_CSR_TABLE1_BASE 0x0380 |
55 | #define IPW_CSR_TABLE2_BASE 0x0384 |
56 | #define IPW_CSR_TX_WRITE 0x0f80 |
57 | #define IPW_CSR_RX_WRITE 0x0fa0 |
58 | |
59 | /* possible flags for register IPW_CSR_INTR */ |
60 | #define IPW_INTR_TX_TRANSFER 0x00000001 |
61 | #define IPW_INTR_RX_TRANSFER 0x00000002 |
62 | #define IPW_INTR_STATUS_CHANGE 0x00000010 |
63 | #define IPW_INTR_COMMAND_DONE 0x00010000 |
64 | #define IPW_INTR_FW_INIT_DONE 0x01000000 |
65 | #define IPW_INTR_FATAL_ERROR 0x40000000 |
66 | #define IPW_INTR_PARITY_ERROR 0x80000000 |
67 | |
68 | #define IPW_INTR_MASK \ |
69 | (IPW_INTR_TX_TRANSFER | IPW_INTR_RX_TRANSFER | \ |
70 | IPW_INTR_STATUS_CHANGE | IPW_INTR_COMMAND_DONE | \ |
71 | IPW_INTR_FW_INIT_DONE | IPW_INTR_FATAL_ERROR | \ |
72 | IPW_INTR_PARITY_ERROR) |
73 | |
74 | /* possible flags for register IPW_CSR_RST */ |
75 | #define IPW_RST_PRINCETON_RESET 0x00000001 |
76 | #define IPW_RST_SW_RESET 0x00000080 |
77 | #define IPW_RST_MASTER_DISABLED 0x00000100 |
78 | #define IPW_RST_STOP_MASTER 0x00000200 |
79 | |
80 | /* possible flags for register IPW_CSR_CTL */ |
81 | #define IPW_CTL_CLOCK_READY 0x00000001 |
82 | #define IPW_CTL_ALLOW_STANDBY 0x00000002 |
83 | #define IPW_CTL_INIT 0x00000004 |
84 | |
85 | /* possible flags for register IPW_CSR_IO */ |
86 | #define IPW_IO_GPIO1_ENABLE 0x00000008 |
87 | #define IPW_IO_GPIO1_MASK 0x0000000c |
88 | #define IPW_IO_GPIO3_MASK 0x000000c0 |
89 | #define IPW_IO_LED_OFF 0x00002000 |
90 | #define IPW_IO_RADIO_DISABLED 0x00010000 |
91 | |
92 | #define IPW_STATE_ASSOCIATED 0x0004 |
93 | #define IPW_STATE_ASSOCIATION_LOST 0x0008 |
94 | #define IPW_STATE_SCAN_COMPLETE 0x0020 |
95 | #define IPW_STATE_RADIO_DISABLED 0x0100 |
96 | #define IPW_STATE_DISABLED 0x0200 |
97 | #define IPW_STATE_SCANNING 0x0800 |
98 | |
99 | /* table1 offsets */ |
100 | #define IPW_INFO_LOCK 480 |
101 | #define IPW_INFO_APS_CNT 604 |
102 | #define IPW_INFO_APS_BASE 608 |
103 | #define IPW_INFO_CARD_DISABLED 628 |
104 | #define IPW_INFO_CURRENT_CHANNEL 756 |
105 | #define IPW_INFO_CURRENT_TX_RATE 768 |
106 | #define IPW_INFO_EEPROM_ADDRESS 816 |
107 | |
108 | |
109 | /* table2 offsets */ |
110 | #define IPW_INFO_CURRENT_SSID 48 |
111 | #define IPW_INFO_CURRENT_BSSID 112 |
112 | |
113 | /* supported rates */ |
114 | #define IPW_RATE_DS1 1 |
115 | #define IPW_RATE_DS2 2 |
116 | #define IPW_RATE_DS5 4 |
117 | #define IPW_RATE_DS11 8 |
118 | |
119 | /* firmware binary image header */ |
120 | struct ipw_firmware_hdr { |
121 | u_int32_t version; |
122 | u_int32_t main_size; /* firmware size */ |
123 | u_int32_t ucode_size; /* microcode size */ |
124 | } __packed; |
125 | |
126 | /* buffer descriptor */ |
127 | struct ipw_bd { |
128 | u_int32_t physaddr; |
129 | u_int32_t len; |
130 | u_int8_t flags; |
131 | #define IPW_BD_FLAG_TX_FRAME_802_3 0x00 |
132 | #define IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT 0x01 |
133 | #define IPW_BD_FLAG_TX_FRAME_COMMAND 0x02 |
134 | #define IPW_BD_FLAG_TX_FRAME_802_11 0x04 |
135 | #define IPW_BD_FLAG_TX_LAST_FRAGMENT 0x08 |
136 | u_int8_t nfrag; /* number of fragments */ |
137 | u_int8_t reserved[6]; |
138 | } __packed; |
139 | |
140 | /* status */ |
141 | struct ipw_status { |
142 | u_int32_t len; |
143 | u_int16_t code; |
144 | #define IPW_STATUS_CODE_COMMAND 0 |
145 | #define IPW_STATUS_CODE_NEWSTATE 1 |
146 | #define IPW_STATUS_CODE_DATA_802_11 2 |
147 | #define IPW_STATUS_CODE_DATA_802_3 3 |
148 | #define IPW_STATUS_CODE_NOTIFICATION 4 |
149 | u_int8_t flags; |
150 | #define IPW_STATUS_FLAG_DECRYPTED 0x01 |
151 | #define IPW_STATUS_FLAG_WEP_ENCRYPTED 0x02 |
152 | u_int8_t ; /* received signal strength indicator */ |
153 | } __packed; |
154 | |
155 | /* data header */ |
156 | struct ipw_hdr { |
157 | u_int32_t type; |
158 | #define IPW_HDR_TYPE_SEND 33 |
159 | u_int32_t subtype; |
160 | u_int8_t encrypted; |
161 | u_int8_t encrypt; |
162 | u_int8_t keyidx; |
163 | u_int8_t keysz; |
164 | u_int8_t key[IEEE80211_KEYBUF_SIZE]; |
165 | u_int8_t reserved[10]; |
166 | u_int8_t src_addr[IEEE80211_ADDR_LEN]; |
167 | u_int8_t dst_addr[IEEE80211_ADDR_LEN]; |
168 | u_int16_t fragmentsz; |
169 | } __packed; |
170 | |
171 | /* command */ |
172 | struct ipw_cmd { |
173 | u_int32_t type; |
174 | #define IPW_CMD_ENABLE 2 |
175 | #define IPW_CMD_SET_CONFIGURATION 6 |
176 | #define IPW_CMD_SET_ESSID 8 |
177 | #define IPW_CMD_SET_MANDATORY_BSSID 9 |
178 | #define IPW_CMD_SET_MAC_ADDRESS 11 |
179 | #define IPW_CMD_SET_MODE 12 |
180 | #define IPW_CMD_SET_CHANNEL 14 |
181 | #define IPW_CMD_SET_RTS_THRESHOLD 15 |
182 | #define IPW_CMD_SET_FRAG_THRESHOLD 16 |
183 | #define IPW_CMD_SET_POWER_MODE 17 |
184 | #define IPW_CMD_SET_TX_RATES 18 |
185 | #define IPW_CMD_SET_BASIC_TX_RATES 19 |
186 | #define IPW_CMD_SET_WEP_KEY 20 |
187 | #define IPW_CMD_SET_WEP_KEY_INDEX 25 |
188 | #define IPW_CMD_SET_WEP_FLAGS 26 |
189 | #define IPW_CMD_ADD_MULTICAST 27 |
190 | #define IPW_CMD_SET_BEACON_INTERVAL 29 |
191 | #define IPW_CMD_SET_TX_POWER_INDEX 36 |
192 | #define IPW_CMD_BROADCAST_SCAN 43 |
193 | #define IPW_CMD_DISABLE 44 |
194 | #define IPW_CMD_SET_DESIRED_BSSID 45 |
195 | #define IPW_CMD_SET_SCAN_OPTIONS 46 |
196 | #define IPW_CMD_PREPARE_POWER_DOWN 58 |
197 | #define IPW_CMD_DISABLE_PHY 61 |
198 | #define IPW_CMD_SET_SECURITY_INFORMATION 67 |
199 | #define IPW_CMD_SET_WPA_IE 69 |
200 | u_int32_t subtype; |
201 | u_int32_t seq; |
202 | u_int32_t len; |
203 | u_int8_t data[400]; |
204 | u_int32_t status; |
205 | u_int8_t reserved[68]; |
206 | } __packed; |
207 | |
208 | /* possible values for command IPW_CMD_SET_POWER_MODE */ |
209 | #define IPW_POWER_MODE_CAM 0 |
210 | #define IPW_POWER_AUTOMATIC 6 |
211 | |
212 | /* possible values for command IPW_CMD_SET_MODE */ |
213 | #define IPW_MODE_BSS 0 |
214 | #define IPW_MODE_IBSS 1 |
215 | #define IPW_MODE_MONITOR 2 |
216 | |
217 | /* possible flags for command IPW_CMD_SET_WEP_FLAGS */ |
218 | #define IPW_WEPON 0x8 |
219 | |
220 | /* structure for command IPW_CMD_SET_WEP_KEY */ |
221 | struct ipw_wep_key { |
222 | u_int8_t idx; |
223 | u_int8_t len; |
224 | u_int8_t key[13]; |
225 | } __packed; |
226 | |
227 | /* structure for command IPW_CMD_SET_SECURITY_INFORMATION */ |
228 | struct ipw_security { |
229 | u_int32_t ciphers; |
230 | #define IPW_CIPHER_NONE 0x00000001 |
231 | #define IPW_CIPHER_WEP40 0x00000002 |
232 | #define IPW_CIPHER_TKIP 0x00000004 |
233 | #define IPW_CIPHER_CCMP 0x00000010 |
234 | #define IPW_CIPHER_WEP104 0x00000020 |
235 | #define IPW_CIPHER_CKIP 0x00000040 |
236 | u_int16_t reserved1; |
237 | u_int8_t authmode; |
238 | #define IPW_AUTH_OPEN 0 |
239 | #define IPW_AUTH_SHARED 1 |
240 | u_int16_t reserved2; |
241 | } __packed; |
242 | |
243 | /* structure for command IPW_CMD_SET_SCAN_OPTIONS */ |
244 | struct ipw_scan_options { |
245 | u_int32_t flags; |
246 | #define IPW_SCAN_DO_NOT_ASSOCIATE 0x00000001 |
247 | #define IPW_SCAN_PASSIVE 0x00000008 |
248 | u_int32_t channels; |
249 | } __packed; |
250 | |
251 | /* structure for command IPW_CMD_SET_CONFIGURATION */ |
252 | struct ipw_configuration { |
253 | u_int32_t flags; |
254 | #define IPW_CFG_PROMISCUOUS 0x00000004 |
255 | #define IPW_CFG_PREAMBLE_AUTO 0x00000010 |
256 | #define IPW_CFG_IBSS_AUTO_START 0x00000020 |
257 | #define IPW_CFG_802_1x_ENABLE 0x00004000 |
258 | #define IPW_CFG_BSS_MASK 0x00008000 |
259 | #define IPW_CFG_IBSS_MASK 0x00010000 |
260 | u_int32_t bss_chan; |
261 | u_int32_t ibss_chan; |
262 | } __packed; |
263 | |
264 | /* structure for command IPW_CMD_SET_WPA_IE */ |
265 | struct ipw_wpa_ie { |
266 | u_int16_t mask; |
267 | u_int16_t capinfo; |
268 | u_int16_t lintval; |
269 | u_int8_t bssid[IEEE80211_ADDR_LEN]; |
270 | u_int32_t len; |
271 | struct ieee80211_ie_wpa ie; |
272 | } __packed; |
273 | |
274 | /* element in AP table */ |
275 | struct ipw_node { |
276 | u_int32_t reserved1[2]; |
277 | u_int8_t bssid[IEEE80211_ADDR_LEN]; |
278 | u_int8_t chan; |
279 | u_int8_t rates; |
280 | u_int16_t reserved2; |
281 | u_int16_t capinfo; |
282 | u_int16_t reserved3; |
283 | u_int16_t intval; |
284 | u_int8_t reserved4[28]; |
285 | u_int8_t essid[IEEE80211_NWID_LEN]; |
286 | u_int16_t reserved5; |
287 | u_int8_t esslen; |
288 | u_int8_t reserved6[7]; |
289 | u_int8_t ; |
290 | } __packed; |
291 | |
292 | /* EEPROM = Electrically Erasable Programmable Read-Only Memory */ |
293 | |
294 | #define IPW_MEM_EEPROM_CTL 0x00300040 |
295 | |
296 | #define IPW_EEPROM_RADIO 0x11 |
297 | #define IPW_EEPROM_MAC 0x21 |
298 | #define IPW_EEPROM_CHANNEL_LIST 0x37 |
299 | |
300 | #define IPW_EEPROM_DELAY 1 /* minimum hold time (microsecond) */ |
301 | |
302 | #define IPW_EEPROM_C (1 << 0) /* Serial Clock */ |
303 | #define IPW_EEPROM_S (1 << 1) /* Chip Select */ |
304 | #define IPW_EEPROM_D (1 << 2) /* Serial data input */ |
305 | #define IPW_EEPROM_Q (1 << 4) /* Serial data output */ |
306 | |
307 | #define IPW_EEPROM_SHIFT_D 2 |
308 | #define IPW_EEPROM_SHIFT_Q 4 |
309 | |
310 | /* |
311 | * control and status registers access macros |
312 | */ |
313 | #define CSR_READ_1(sc, reg) \ |
314 | bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg)) |
315 | |
316 | #define CSR_READ_2(sc, reg) \ |
317 | bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg)) |
318 | |
319 | #define CSR_READ_4(sc, reg) \ |
320 | bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) |
321 | |
322 | #define CSR_WRITE_1(sc, reg, val) \ |
323 | bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val)) |
324 | |
325 | #define CSR_WRITE_2(sc, reg, val) \ |
326 | bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val)) |
327 | |
328 | #define CSR_WRITE_4(sc, reg, val) \ |
329 | bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) |
330 | |
331 | #define CSR_WRITE_MULTI_1(sc, reg, buf, len) \ |
332 | bus_space_write_multi_1((sc)->sc_st, (sc)->sc_sh, (reg), \ |
333 | (buf), (len)) |
334 | |
335 | /* |
336 | * indirect memory space access macros |
337 | */ |
338 | #define MEM_WRITE_1(sc, addr, val) do { \ |
339 | CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr)); \ |
340 | CSR_WRITE_1((sc), IPW_CSR_INDIRECT_DATA, (val)); \ |
341 | } while (/* CONSTCOND */0) |
342 | |
343 | #define MEM_WRITE_2(sc, addr, val) do { \ |
344 | CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr)); \ |
345 | CSR_WRITE_2((sc), IPW_CSR_INDIRECT_DATA, (val)); \ |
346 | } while (/* CONSTCOND */0) |
347 | |
348 | #define MEM_WRITE_4(sc, addr, val) do { \ |
349 | CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr)); \ |
350 | CSR_WRITE_4((sc), IPW_CSR_INDIRECT_DATA, (val)); \ |
351 | } while (/* CONSTCOND */0) |
352 | |
353 | #define MEM_WRITE_MULTI_1(sc, addr, buf, len) do { \ |
354 | CSR_WRITE_4((sc), IPW_CSR_INDIRECT_ADDR, (addr)); \ |
355 | CSR_WRITE_MULTI_1((sc), IPW_CSR_INDIRECT_DATA, (buf), (len)); \ |
356 | } while (/* CONSTCOND */0) |
357 | |
358 | /* |
359 | * EEPROM access macro |
360 | */ |
361 | #define IPW_EEPROM_CTL(sc, val) do { \ |
362 | MEM_WRITE_4((sc), IPW_MEM_EEPROM_CTL, (val)); \ |
363 | DELAY(IPW_EEPROM_DELAY); \ |
364 | } while (0) |
365 | |