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
|
/* $OpenBSD: if_ipwreg.h,v 1.16 2008/08/28 15:08:38 damien Exp $ */
/*-
* Copyright (c) 2004-2008
* Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#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 {
uint32_t version;
uint32_t main_size; /* firmware size */
uint32_t ucode_size; /* microcode size */
} __packed;
/* buffer descriptor */
struct ipw_bd {
uint32_t physaddr;
uint32_t len;
uint8_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
uint8_t nfrag; /* number of fragments */
uint8_t reserved[6];
} __packed;
/* status */
struct ipw_status {
uint32_t len;
uint16_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
uint8_t flags;
#define IPW_STATUS_FLAG_DECRYPTED 0x01
#define IPW_STATUS_FLAG_WEP_ENCRYPTED 0x02
uint8_t rssi; /* received signal strength indicator */
} __packed;
/* data header */
struct ipw_hdr {
uint32_t type;
#define IPW_HDR_TYPE_SEND 33
uint32_t subtype;
uint8_t encrypted;
uint8_t encrypt;
uint8_t keyidx;
uint8_t keysz;
uint8_t key[IEEE80211_KEYBUF_SIZE];
uint8_t reserved[10];
uint8_t src_addr[IEEE80211_ADDR_LEN];
uint8_t dst_addr[IEEE80211_ADDR_LEN];
uint16_t fragmentsz;
} __packed;
/* command */
struct ipw_cmd {
uint32_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_PRIVACY_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_MSDU_TX_RATES 62
#define IPW_CMD_SET_SECURITY_INFORMATION 67
#define IPW_CMD_SET_ASSOC_REQ 69
uint32_t subtype;
uint32_t seq;
uint32_t len;
uint8_t data[400];
uint32_t status;
uint8_t reserved[68];
} __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_PRIVACY_FLAGS */
#define IPW_PRIVACYON 0x8
/* structure for command IPW_CMD_SET_WEP_KEY */
struct ipw_wep_key {
uint8_t idx;
uint8_t len;
uint8_t key[13];
} __packed;
/* structure for command IPW_CMD_SET_SECURITY_INFORMATION */
struct ipw_security {
uint32_t ciphers;
#define IPW_CIPHER_NONE 0x00000001
#define IPW_CIPHER_WEP40 0x00000002
#define IPW_CIPHER_TKIP 0x00000004
#define IPW_CIPHER_CCMP 0x00000010
#define IPW_CIPHER_WEP104 0x00000020
uint16_t reserved1;
uint8_t authmode;
#define IPW_AUTH_OPEN 0
#define IPW_AUTH_SHARED 1
uint16_t reserved2;
} __packed;
/* structure for command IPW_CMD_SET_SCAN_OPTIONS */
struct ipw_scan_options {
uint32_t flags;
#define IPW_SCAN_DO_NOT_ASSOCIATE 0x00000001
#define IPW_SCAN_MIXED_CELL 0x00000002
#define IPW_SCAN_PASSIVE 0x00000008
uint32_t channels;
} __packed;
/* structure for command IPW_CMD_SET_CONFIGURATION */
struct ipw_configuration {
uint32_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
uint32_t bss_chan;
uint32_t ibss_chan;
} __packed;
/* structure for command IPW_CMD_SET_ASSOC_REQ */
struct ipw_assoc_req {
uint16_t flags;
#define IPW_ASSOC_CAPINFO 0x0001
#define IPW_ASSOC_LINTVAL 0x0002
#define IPW_ASSOC_BSSID 0x0004 /* reassoc */
uint16_t capinfo;
uint16_t lintval;
uint8_t bssid[IEEE80211_ADDR_LEN];
uint32_t optie_len;
uint8_t optie[384];
} __packed;
#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 (/* CONSTCOND */0)
|