1 /*
2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2004, 2005
8  *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice unmodified, this list of conditions, and the following
15  *    disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #ifndef _SYS_IPW2200_IMPL_H
34 #define	_SYS_IPW2200_IMPL_H
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 /*
41  * Intel Wireless PRO/2200 mini-pci adapter driver
42  * ipw2200_impl.h includes:
43  * 	. implementation of ipw2200
44  * 	. hardware operations and interface definations for ipw2200
45  * 	. firmware operations and interface definations for ipw2200
46  */
47 #include <sys/ddi.h>
48 #include <sys/sunddi.h>
49 #include <sys/mac.h>
50 #include <sys/mac_wifi.h>
51 #include <sys/net80211.h>
52 
53 /*
54  * Implementation of ipw2200
55  */
56 #define	IPW2200_PCI_CFG_RNUM 	(0) /* pci config space */
57 #define	IPW2200_PCI_CSR_RNUM 	(1) /* device CSR space */
58 #define	IPW2200_PCI_INTR_NUM	(0) /* interrupt number */
59 
60 #define	IPW2200_TX_RING_SIZE 	(64)
61 #define	IPW2200_CMD_RING_SIZE	(16)
62 #define	IPW2200_RX_RING_SIZE 	(32)
63 
64 struct dma_region {
65 	ddi_dma_handle_t	dr_hnd;
66 	ddi_acc_handle_t	dr_acc;
67 	ddi_dma_cookie_t	dr_cookie;
68 	uint_t			dr_ccnt;
69 	uint32_t		dr_pbase;
70 	caddr_t			dr_base;
71 	size_t			dr_size;
72 	const char		*dr_name;
73 };
74 
75 struct ipw2200_firmware {
76 	uint8_t			*boot_base; /* boot code */
77 	size_t			boot_size;
78 	uint8_t			*uc_base; /* u-controller code */
79 	size_t			uc_size;
80 	uint8_t			*fw_base; /* firmware code */
81 	size_t			fw_size;
82 };
83 
84 /*
85  * besides the statistic counted by net80211, driver can also record
86  * statistic data while process
87  */
88 struct ipw2200_stats {
89 	uint32_t		sc_rx_len_err;
90 	uint32_t		sc_tx_discard;
91 	uint32_t		sc_tx_alloc_fail;
92 	uint32_t		sc_tx_encap_fail;
93 	uint32_t		sc_tx_crypto_fail;
94 };
95 
96 /*
97  * per-instance soft-state structure
98  */
99 struct ipw2200_softc {
100 	struct ieee80211com	sc_ic;
101 	dev_info_t		*sc_dip;
102 	int	(*sc_newstate)(struct ieee80211com *,
103 	    enum ieee80211_state, int);
104 	void    (*sc_node_free)(struct ieee80211com *);
105 	int			sc_authmode;
106 
107 	/* CSR */
108 	ddi_acc_handle_t	sc_ioh;
109 	caddr_t			sc_regs;
110 	/* mutex to protect interrupt handler */
111 	kmutex_t		sc_ilock;
112 	/* interrupt iblock cookie */
113 	ddi_iblock_cookie_t 	sc_iblk;
114 	/* soft interrupt */
115 	ddi_softintr_t		sc_link_softint;
116 	/* link status */
117 	int32_t			sc_linkstate;
118 	/* flags */
119 	uint32_t		sc_flags;
120 #define	IPW2200_FLAG_FW_CACHED		(1 << 0)
121 #define	IPW2200_FLAG_FW_INITED		(1 << 1)
122 #define	IPW2200_FLAG_RUNNING		(1 << 2)
123 #define	IPW2200_FLAG_LINK_CHANGE	(1 << 3)
124 #define	IPW2200_FLAG_TX_SCHED		(1 << 4)
125 #define	IPW2200_FLAG_SCANNING		(1 << 5)
126 #define	IPW2200_FLAG_HW_ERR_RECOVER	(1 << 6)
127 #define	IPW2200_FLAG_ASSOCIATED		(1 << 7)
128 #define	IPW2200_FLAG_SUSPEND		(1 << 8)
129 #define	IPW2200_FLAG_QUIESCED		(1 << 9)
130 #define	IPW2200_FLAG_HAS_RADIO_SWITCH	(1 << 16)
131 	/* firmware download */
132 	int			sc_fw_ok;
133 	kcondvar_t		sc_fw_cond;
134 
135 	/* command desc ring */
136 	kmutex_t		sc_cmd_lock;
137 	kcondvar_t		sc_cmd_cond;
138 	uint32_t		sc_cmd_cur;
139 	uint32_t		sc_cmd_free;
140 	struct ipw2200_cmd_desc	*sc_cmdsc;
141 
142 	/* command status */
143 	int			sc_done[IPW2200_CMD_RING_SIZE];
144 	kcondvar_t		sc_cmd_status_cond;
145 
146 	/* tx ring, bd->hdr&buf */
147 	kmutex_t		sc_tx_lock;
148 	uint32_t		sc_tx_cur;
149 	uint32_t		sc_tx_free;
150 	struct ipw2200_tx_desc	*sc_txdsc;
151 	uint8_t			*sc_txbufs[IPW2200_TX_RING_SIZE];
152 
153 	/* rx ring */
154 	uint32_t		sc_rx_cur;
155 	uint32_t		sc_rx_free;
156 	uint8_t			*sc_rxbufs[IPW2200_RX_RING_SIZE];
157 
158 	/* tx-desc & tx-buffer array */
159 	struct dma_region	sc_dma_txdsc;
160 	struct dma_region	sc_dma_txbufs[IPW2200_TX_RING_SIZE];
161 	struct dma_region	sc_dma_cmdsc;
162 	/* rx-buffer array */
163 	struct dma_region	sc_dma_rxbufs[IPW2200_RX_RING_SIZE];
164 
165 	/* hw configuration values */
166 	uint8_t			sc_macaddr[IEEE80211_ADDR_LEN];
167 	/* MAC address string */
168 	char			sc_macstr[32];
169 
170 	/* firmware */
171 	struct ipw2200_firmware	sc_fw;
172 
173 	/* reschedule lock */
174 	kmutex_t		sc_resched_lock;
175 
176 	/* pci information */
177 	uint16_t		sc_vendor, sc_device, sc_subven, sc_subdev;
178 
179 	/* statistic counting by driver */
180 	struct ipw2200_stats	sc_stats;
181 
182 	/* mfthread related, mfthread is used to handle asynchronous task */
183 	kthread_t		*sc_mf_thread;
184 	kmutex_t		sc_mflock;
185 	int			sc_mfthread_switch;
186 	kcondvar_t		sc_mfthread_req;
187 	kcondvar_t		sc_mfthread_cv;
188 
189 };
190 
191 /*
192  * RING_BACKWARD - move 'x' backward 's' steps in a 'b'- sized ring
193  * RING_FORWARD	 - move 'x' forward 's' steps in a 'b'- sized ring
194  *
195  * note that there must be 0 <= 'x' < 'b' && 0 <= 's' < 'b'
196  */
197 #define	RING_FLEN(x, y, b)	((((x) > (y)) ? ((b)+(y)-(x)) : ((y)-(x))))
198 #define	RING_FORWARD(x, s, b)	(((x)+(s))%(b))
199 #define	RING_BACKWARD(x, s, b)	RING_FORWARD((x), (b)-(s), (b))
200 
201 extern int ipw2200_init(struct ipw2200_softc *sc);
202 extern void ipw2200_wifi_ioctl(struct ipw2200_softc *, queue_t *,
203     mblk_t *, uint32_t);
204 extern int ipw2200_dma_region_alloc(struct ipw2200_softc *sc,
205     struct dma_region *dr, size_t size, uint_t dir, uint_t flags);
206 extern void ipw2200_dma_region_free(struct dma_region *dr);
207 extern int ipw2200_disable(struct ipw2200_softc *sc);
208 extern int ipw2200_start_scan(struct ipw2200_softc *sc);
209 
210 /*
211  * get radio off/on status
212  */
213 extern int ipw2200_radio_status(struct ipw2200_softc *sc);
214 
215 /*
216  * Below structure and functions will be used for statistic, which will be
217  * displayed when the wificonfig running...
218  */
219 struct statistic {
220 	int		index;
221 	const char	*desc;
222 };
223 extern void ipw2200_get_statistics(struct ipw2200_softc *sc);
224 
225 /*
226  * Hardware related definations and interfaces.
227  */
228 #define	IPW2200_CSR_INTR		(0x0008)
229 #define	IPW2200_CSR_INTR_MASK		(0x000c)
230 #define	IPW2200_CSR_INDIRECT_ADDR	(0x0010)
231 #define	IPW2200_CSR_INDIRECT_DATA	(0x0014)
232 #define	IPW2200_CSR_AUTOINC_ADDR	(0x0018)
233 #define	IPW2200_CSR_AUTOINC_DATA	(0x001c)
234 #define	IPW2200_CSR_RST			(0x0020)
235 #define	IPW2200_CSR_CTL			(0x0024)
236 #define	IPW2200_CSR_IO			(0x0030)
237 #define	IPW2200_CSR_CMD_BASE		(0x0200)
238 #define	IPW2200_CSR_CMD_SIZE		(0x0204)
239 #define	IPW2200_CSR_TX1_BASE		(0x0208)
240 #define	IPW2200_CSR_TX1_SIZE		(0x020c)
241 #define	IPW2200_CSR_TX2_BASE		(0x0210)
242 #define	IPW2200_CSR_TX2_SIZE		(0x0214)
243 #define	IPW2200_CSR_TX3_BASE		(0x0218)
244 #define	IPW2200_CSR_TX3_SIZE		(0x021c)
245 #define	IPW2200_CSR_TX4_BASE		(0x0220)
246 #define	IPW2200_CSR_TX4_SIZE		(0x0224)
247 #define	IPW2200_CSR_CMD_READ_INDEX	(0x0280)
248 #define	IPW2200_CSR_TX1_READ_INDEX	(0x0284)
249 #define	IPW2200_CSR_TX2_READ_INDEX	(0x0288)
250 #define	IPW2200_CSR_TX3_READ_INDEX	(0x028c)
251 #define	IPW2200_CSR_TX4_READ_INDEX	(0x0290)
252 #define	IPW2200_CSR_RX_READ_INDEX	(0x02a0)
253 #define	IPW2200_CSR_RX_BASE		(0x0500)
254 #define	IPW2200_CSR_TABLE0_SIZE		(0x0700)
255 #define	IPW2200_CSR_TABLE0_BASE		(0x0704)
256 #define	IPW2200_CSR_NODE_BASE		(0x0c0c)
257 #define	IPW2200_CSR_CMD_WRITE_INDEX	(0x0f80)
258 #define	IPW2200_CSR_TX1_WRITE_INDEX	(0x0f84)
259 #define	IPW2200_CSR_TX2_WRITE_INDEX	(0x0f88)
260 #define	IPW2200_CSR_TX3_WRITE_INDEX	(0x0f8c)
261 #define	IPW2200_CSR_TX4_WRITE_INDEX	(0x0f90)
262 #define	IPW2200_CSR_RX_WRITE_INDEX	(0x0fa0)
263 #define	IPW2200_CSR_READ_INT		(0x0ff4)
264 
265 #define	IPW2200_CSR_CURRENTT_TX_RATE	IPW2200_CSR_TABLE0_BASE
266 
267 /*
268  * CSR flags: IPW2200_CSR_INTR
269  */
270 #define	IPW2200_INTR_RX_TRANSFER	(0x00000002)
271 #define	IPW2200_INTR_CMD_TRANSFER	(0x00000800)
272 #define	IPW2200_INTR_TX1_TRANSFER	(0x00001000)
273 #define	IPW2200_INTR_TX2_TRANSFER	(0x00002000)
274 #define	IPW2200_INTR_TX3_TRANSFER	(0x00004000)
275 #define	IPW2200_INTR_TX4_TRANSFER	(0x00008000)
276 #define	IPW2200_INTR_FW_INITED		(0x01000000)
277 #define	IPW2200_INTR_RADIO_OFF		(0x04000000)
278 #define	IPW2200_INTR_FATAL_ERROR	(0x40000000)
279 #define	IPW2200_INTR_PARITY_ERROR	(0x80000000)
280 
281 #define	IPW2200_INTR_MASK_ALL	(IPW2200_INTR_RX_TRANSFER	| \
282 	IPW2200_INTR_CMD_TRANSFER	| \
283 	IPW2200_INTR_TX1_TRANSFER	| \
284 	IPW2200_INTR_TX2_TRANSFER	| \
285 	IPW2200_INTR_TX3_TRANSFER	| \
286 	IPW2200_INTR_TX4_TRANSFER	| \
287 	IPW2200_INTR_FW_INITED		| \
288 	IPW2200_INTR_RADIO_OFF		| \
289 	IPW2200_INTR_FATAL_ERROR	| \
290 	IPW2200_INTR_PARITY_ERROR)
291 
292 #define	IPW2200_INTR_MASK_ERR	(IPW2200_INTR_FATAL_ERROR	| \
293 	IPW2200_INTR_PARITY_ERROR)
294 
295 /*
296  * CSR flags for register: IPW2200_CSR_RST, which is used to reset h/w
297  */
298 #define	IPW2200_RST_PRINCETON_RESET	(0x00000001)
299 #define	IPW2200_RST_STANDBY		(0x00000004)
300 #define	IPW2200_RST_LED_ACTIVITY	(0x00000010)
301 #define	IPW2200_RST_LED_ASSOCIATED	(0x00000020)
302 #define	IPW2200_RST_LED_OFDM		(0x00000040)
303 #define	IPW2200_RST_SW_RESET		(0x00000080)
304 #define	IPW2200_RST_MASTER_DISABLED	(0x00000100)
305 #define	IPW2200_RST_STOP_MASTER		(0x00000200)
306 #define	IPW2200_RST_GATE_ODMA		(0x02000000)
307 #define	IPW2200_RST_GATE_IDMA		(0x04000000)
308 #define	IPW2200_RST_GATE_ADMA		(0x20000000)
309 
310 /*
311  * CSR flags for register: IPW2200_CSR_CTL
312  */
313 #define	IPW2200_CTL_CLOCK_READY		(0x00000001)
314 #define	IPW2200_CTL_ALLOW_STANDBY	(0x00000002)
315 #define	IPW2200_CTL_INIT		(0x00000004)
316 
317 /*
318  * CSR flags for register: IPW2200_CSR_IO
319  */
320 #define	IPW2200_IO_RADIO_ENABLED	(0x00010000)
321 
322 /*
323  * CSR flags for register: IPW2200_CSR_READ_INT
324  */
325 #define	IPW2200_READ_INT_INIT_HOST	(0x20000000)
326 
327 /* table2 offsets */
328 #define	IPW2200_INFO_ADAPTER_MAC	(40)
329 
330 /* constants for command blocks */
331 #define	IPW2200_CB_DEFAULT_CTL		(0x8cea0000)
332 #define	IPW2200_CB_MAXDATALEN		(8191)
333 
334 /* supported rates */
335 #define	IPW2200_RATE_DS1		(10)
336 #define	IPW2200_RATE_DS2		(20)
337 #define	IPW2200_RATE_DS5		(55)
338 #define	IPW2200_RATE_DS11		(110)
339 #define	IPW2200_RATE_OFDM6		(13)
340 #define	IPW2200_RATE_OFDM9		(15)
341 #define	IPW2200_RATE_OFDM12		(5)
342 #define	IPW2200_RATE_OFDM18		(7)
343 #define	IPW2200_RATE_OFDM24		(9)
344 #define	IPW2200_RATE_OFDM36		(11)
345 #define	IPW2200_RATE_OFDM48		(1)
346 #define	IPW2200_RATE_OFDM54		(3)
347 
348 #pragma pack(1)
349 /* HW structures, packed */
350 
351 struct ipw2200_hdr {
352 	uint8_t		type;
353 #define	IPW2200_HDR_TYPE_DATA		(0)
354 #define	IPW2200_HDR_TYPE_COMMAND	(1)
355 #define	IPW2200_HDR_TYPE_NOTIF		(3)
356 #define	IPW2200_HDR_TYPE_FRAME		(9)
357 	uint8_t		seq;
358 	uint8_t		flags;
359 #define	IPW2200_HDR_FLAG_IRQ		(0x04)
360 	uint8_t		reserved;
361 };
362 
363 struct ipw2200_notif {
364 	uint32_t	reserved[2];
365 	uint8_t		type;
366 #define	IPW2200_NOTIF_TYPE_SUCCESS		(0)
367 #define	IPW2200_NOTIF_TYPE_UNSPECIFIED		(1)
368 #define	IPW2200_NOTIF_TYPE_ASSOCIATION		(10)
369 #define	IPW2200_NOTIF_TYPE_AUTHENTICATION	(11)
370 #define	IPW2200_NOTIF_TYPE_SCAN_CHANNEL		(12)
371 #define	IPW2200_NOTIF_TYPE_SCAN_COMPLETE	(13)
372 #define	IPW2200_NOTIF_TYPE_FRAG_LENGTH		(14)
373 #define	IPW2200_NOTIF_TYPE_LINK_QUALITY		(15)
374 #define	IPW2200_NOTIF_TYPE_BEACON		(17)
375 #define	IPW2200_NOTIF_TYPE_TGI_TX_KEY		(18)
376 #define	IPW2200_NOTIF_TYPE_CALIBRATION		(20)
377 #define	IPW2200_NOTIF_TYPE_NOISE		(25)
378 	uint8_t		flags;
379 	uint16_t	len;
380 };
381 
382 /*
383  * structure for notification IPW2200_NOTIF_TYPE_AUTHENTICATION
384  */
385 struct ipw2200_notif_authentication {
386 	uint8_t		state;
387 #define	IPW2200_AUTH_FAIL	(0)
388 #define	IPW2200_AUTH_SENT_1	(1)
389 #define	IPW2200_AUTH_RECV_2	(2)
390 #define	IPW2200_AUTH_SEQ1_PASS	(3)
391 #define	IPW2200_AUTH_SEQ1_FAIL	(4)
392 #define	IPW2200_AUTH_SUCCESS	(9)
393 };
394 
395 /*
396  * structure for notification IPW2200_NOTIF_TYPE_ASSOCIATION
397  */
398 struct ipw2200_notif_association {
399 	uint8_t		state;
400 #define	IPW2200_ASSOC_FAIL	(0)
401 #define	IPW2200_ASSOC_SUCCESS	(12)
402 	struct ieee80211_frame	frame;
403 	uint16_t	capinfo;
404 	uint16_t	status;
405 	uint16_t	associd;
406 };
407 
408 /*
409  * structure for notification BACAON
410  */
411 struct ipw2200_notif_beacon_state {
412 	uint32_t	state;
413 #define	IPW2200_BEACON_MISS	(1)
414 	uint32_t	number;
415 };
416 
417 /*
418  * structure for notification IPW2200_NOTIF_TYPE_SCAN_CHANNEL
419  */
420 struct ipw2200_notif_scan_channel {
421 	uint8_t		nchan;
422 	uint8_t		reserved[47];
423 };
424 
425 /*
426  * structure for notification IPW2200_NOTIF_TYPE_SCAN_COMPLETE
427  */
428 struct ipw2200_notif_scan_complete {
429 	uint8_t		type;
430 	uint8_t		nchan;
431 	uint8_t		status;
432 	uint8_t		reserved;
433 };
434 
435 /*
436  * received frame header
437  */
438 struct ipw2200_frame {
439 	uint32_t	reserved1[2];
440 	uint8_t		chan;
441 	uint8_t		status;
442 	uint8_t		rate;
443 	uint8_t		rssi; /* receiver signal strength indicator */
444 	uint8_t		agc; /* automatic gain control */
445 	uint8_t		rssi_dbm;
446 	uint16_t	signal;
447 	uint16_t	noise;
448 	uint8_t		antenna;
449 	uint8_t		control;
450 	uint8_t		reserved3[2];
451 	uint16_t	len;
452 };
453 
454 /*
455  * header for transmission
456  */
457 struct ipw2200_tx_desc {
458 	struct ipw2200_hdr	hdr;
459 	uint32_t	reserved1;
460 	uint8_t		station;
461 	uint8_t		reserved2[3];
462 	uint8_t		cmd;
463 #define	IPW2200_DATA_CMD_TX		(0x0b)
464 	uint8_t		seq;
465 	uint16_t	len;
466 	uint8_t		priority;
467 	uint8_t		flags;
468 #define	IPW2200_DATA_FLAG_SHPREAMBLE	(0x04)
469 #define	IPW2200_DATA_FLAG_NO_WEP	(0x20)
470 #define	IPW2200_DATA_FLAG_NEED_ACK	(0x80)
471 	uint8_t		xflags;
472 #define	IPW2200_DATA_XFLAG_QOS		(0x10)
473 	uint8_t		wep_txkey;
474 	uint8_t		wepkey[IEEE80211_KEYBUF_SIZE];
475 	uint8_t		rate;
476 	uint8_t		antenna;
477 	uint8_t		reserved3[10];
478 
479 	struct ieee80211_frame_addr4 wh;
480 	uint8_t		reserved4[2];
481 	uint32_t	iv;
482 	uint32_t	eiv;
483 
484 	uint32_t	nseg;
485 #define	IPW2200_MAX_NSEG		(6)
486 	uint32_t	seg_addr[IPW2200_MAX_NSEG];
487 	uint16_t	seg_len[IPW2200_MAX_NSEG];
488 };
489 
490 /*
491  * command
492  */
493 struct ipw2200_cmd_desc {
494 	struct ipw2200_hdr	hdr;
495 	uint8_t			type;
496 #define	IPW2200_CMD_ENABLE		(2)
497 #define	IPW2200_CMD_SET_CONFIG		(6)
498 #define	IPW2200_CMD_SET_ESSID		(8)
499 #define	IPW2200_CMD_SET_MAC_ADDRESS	(11)
500 #define	IPW2200_CMD_SET_RTS_THRESHOLD	(15)
501 #define	IPW2200_CMD_SET_FRAG_THRESHOLD	(16)
502 #define	IPW2200_CMD_SET_POWER_MODE	(17)
503 #define	IPW2200_CMD_SET_WEP_KEY		(18)
504 #define	IPW2200_CMD_SCAN		(20)
505 #define	IPW2200_CMD_ASSOCIATE		(21)
506 #define	IPW2200_CMD_SET_RATES		(22)
507 #define	IPW2200_CMD_ABORT_SCAN		(23)
508 #define	IPW2200_CMD_SET_WME_PARAMS	(25)
509 #define	IPW2200_CMD_SCAN_EXT		(26)
510 #define	IPW2200_CMD_SET_OPTIE		(31)
511 #define	IPW2200_CMD_DISABLE		(33)
512 #define	IPW2200_CMD_SET_IV		(34)
513 #define	IPW2200_CMD_SET_TX_POWER	(35)
514 #define	IPW2200_CMD_SET_SENSITIVITY	(42)
515 #define	IPW2200_CMD_SET_WMEIE		(84)
516 	uint8_t			len;
517 	uint16_t		reserved;
518 	uint8_t			data[120];
519 };
520 
521 /*
522  * node information (IBSS)
523  */
524 struct ipw2200_ibssnode {
525 	uint8_t		bssid[IEEE80211_ADDR_LEN];
526 	uint8_t		reserved[2];
527 };
528 
529 /*
530  * constants for 'mode' fields
531  */
532 #define	IPW2200_MODE_11A	(0)
533 #define	IPW2200_MODE_11B	(1)
534 #define	IPW2200_MODE_11G	(2)
535 
536 /*
537  * macro for command IPW2200_CMD_SET_SENSITIVITY
538  */
539 #define	IPW2200_RSSIDBM2RAW(rssi)((rssi) - 112)
540 
541 /*
542  * possible values for command IPW2200_CMD_SET_POWER_MODE
543  */
544 #define	IPW2200_POWER_MODE_CAM		(0)
545 #define	IPW2200_POWER_MODE_PSP		(3)
546 #define	IPW2200_POWER_MODE_MAX		(5)
547 
548 /*
549  * structure for command IPW2200_CMD_SET_RATES
550  */
551 struct ipw2200_rateset {
552 	uint8_t		mode;
553 	uint8_t		nrates;
554 	uint8_t		type;
555 #define	IPW2200_RATESET_TYPE_NEGOCIATED	(0)
556 #define	IPW2200_RATESET_TYPE_SUPPORTED	(1)
557 	uint8_t		reserved;
558 	uint8_t		rates[12];
559 };
560 
561 /*
562  * structure for command IPW2200_CMD_SET_TX_POWER
563  */
564 struct ipw2200_txpower {
565 	uint8_t		nchan;
566 	uint8_t		mode;
567 	struct {
568 		uint8_t	chan;
569 		uint8_t power;
570 #define	IPW2200_TXPOWER_MAX	(20)
571 #define	IPW2200_TXPOWER_RATIO	(IEEE80211_TXPOWER_MAX / IPW2200_TXPOWER_MAX)
572 	} chan[37];
573 };
574 
575 /*
576  * structure for command IPW2200_CMD_ASSOCIATE
577  */
578 struct ipw2200_associate {
579 	uint8_t		chan;
580 	uint8_t		auth;
581 #define	IPW2200_AUTH_OPEN	(0)
582 #define	IPW2200_AUTH_SHARED	(1)
583 #define	IPW2200_AUTH_NONE	(3)
584 	uint8_t		type;
585 #define	IPW2200_HC_ASSOC	(0)
586 #define	IPW2200_HC_REASSOC	(1)
587 #define	IPW2200_HC_DISASSOC	(2)
588 #define	IPW2200_HC_IBSS_START	(3)
589 #define	IPW2200_HC_IBSS_RECONF	(4)
590 #define	IPW2200_HC_DISASSOC_QUIET (5)
591 	uint8_t		reserved1;
592 	uint16_t	policy;
593 #define	IPW2200_POLICY_WME	(1)
594 #define	IPW2200_POLICY_WPA	(2)
595 	uint8_t		plen;
596 	uint8_t		mode;
597 	uint8_t		bssid[IEEE80211_ADDR_LEN];
598 	uint8_t		tstamp[8];
599 
600 	uint16_t	capinfo;
601 	uint16_t	lintval;
602 	uint16_t	intval;
603 	uint8_t		dst[IEEE80211_ADDR_LEN];
604 	uint32_t	reserved3;
605 	uint16_t	reserved4;
606 };
607 
608 #define	IPW2200_SCAN_CHANNELS	(54)
609 
610 /*
611  * structure for command IPW2200_CMD_SCAN
612  */
613 struct ipw2200_scan {
614 	uint8_t		type;
615 #define	IPW2200_SCAN_TYPE_PASSIVE_STOP	(0) /* passive, stop on first beacon */
616 #define	IPW2200_SCAN_TYPE_PASSIVE	(1) /* passive, full dwell on channel */
617 #define	IPW2200_SCAN_TYPE_DIRECTED	(2) /* active, directed probe seq */
618 #define	IPW2200_SCAN_TYPE_BROADCAST	(3) /* active, bcast probe seq */
619 #define	IPW2200_SCAN_TYPE_BDIRECTED	(4) /* active, directed+bcast probe */
620 #define	IPW2200_SCAN_TYPES		(5)
621 	uint16_t	dwelltime;
622 	uint8_t		channels[IPW2200_SCAN_CHANNELS];
623 #define	IPW2200_CHAN_5GHZ	(0 << 6)
624 #define	IPW2200_CHAN_2GHZ	(1 << 6)
625 	uint8_t		reserved[3];
626 };
627 
628 /*
629  * structure for command IPW2200_CMD_SCAN_EXT
630  */
631 struct ipw2200_scan_ext {
632 	uint32_t	full_scan_index;
633 	uint8_t		channels[IPW2200_SCAN_CHANNELS];
634 	uint8_t		scan_type[IPW2200_SCAN_CHANNELS/2];
635 	uint8_t		reserved;
636 	uint16_t	dwell_time[IPW2200_SCAN_TYPES];
637 };
638 
639 /*
640  * structure for command IPW2200_CMD_SET_CONFIGURATION
641  */
642 struct ipw2200_configuration {
643 	uint8_t		bluetooth_coexistence;
644 	uint8_t		reserved1;
645 	uint8_t		answer_pbreq;
646 	uint8_t		allow_invalid_frames;
647 	uint8_t		multicast_enabled;
648 	uint8_t		drop_unicast_unencrypted;
649 	uint8_t		disable_unicast_decryption;
650 	uint8_t		drop_multicast_unencrypted;
651 	uint8_t		disable_multicast_decryption;
652 	uint8_t		antenna;
653 #define	IPW2200_ANTENNA_AUTO	(0)	/* firmware selects best antenna */
654 #define	IPW2200_ANTENNA_A	(1)	/* use antenna A only */
655 #define	IPW2200_ANTENNA_B	(3)	/* use antenna B only */
656 #define	IPW2200_ANTENNA_SLOWDIV	(2)	/* slow diversity algorithm */
657 	uint8_t		include_crc;
658 	uint8_t		use_protection;
659 	uint8_t		protection_ctsonly;
660 	uint8_t		enable_multicast_filtering;
661 	uint8_t		bluetooth_threshold;
662 	uint8_t		reserved4;
663 	uint8_t		allow_beacon_and_probe_resp;
664 	uint8_t		allow_mgt;
665 	uint8_t		noise_reported;
666 	uint8_t		reserved5;
667 };
668 
669 /*
670  * structure for command IPW2200_CMD_SET_WEP_KEY
671  */
672 struct ipw2200_wep_key {
673 	uint8_t		cmd;
674 #define	IPW2200_WEP_KEY_CMD_SETKEY	(0x08)
675 	uint8_t		seq;
676 	uint8_t		idx;
677 	uint8_t		len;
678 	uint8_t		key[IEEE80211_KEYBUF_SIZE];
679 };
680 
681 /*
682  * the following two structures are for future WME support
683  */
684 struct ipw2200_wme_params {
685 	uint16_t	cwmin[WME_NUM_AC];
686 	uint16_t	cwmax[WME_NUM_AC];
687 	uint8_t		aifsn[WME_NUM_AC];
688 	uint8_t		acm[WME_NUM_AC];
689 	uint16_t	burst[WME_NUM_AC];
690 };
691 
692 struct ipw2200_sensitivity {
693 	uint16_t	rssi;
694 #define	IPW2200_RSSI_TO_DBM	(112)
695 	uint16_t	reserved;
696 };
697 
698 #pragma pack()
699 
700 /*
701  * ROM entries
702  */
703 #define	IPW2200_EEPROM_MAC	(0x21)
704 #define	IPW2200_EEPROM_NIC	(0x25)	/* nic type (lsb) */
705 #define	IPW2200_EEPROM_SKU	(0x25)	/* nic type (msb) */
706 
707 /*
708  * EVENT controls
709  */
710 #define	IPW2200_IMEM_EVENT_CTL	(0x00300004)
711 /*
712  * EEPROM controls
713  */
714 #define	IPW2200_IMEM_EEPROM_CTL	(0x00300040)
715 
716 #define	IPW2200_EEPROM_DELAY	(1) /* minimum hold time(microsecond) */
717 
718 /*
719  * possible flags for register IWI_MEM_EVENT
720  */
721 #define	IPW2200_LED_ASSOC	(1 << 5)
722 #define	IPW2200_LED_MASK	(0xd9fffffb)
723 
724 /*
725  * control and status registers access macros
726  */
727 extern uint8_t ipw2200_csr_get8(struct ipw2200_softc *sc, uint32_t off);
728 extern uint16_t ipw2200_csr_get16(struct ipw2200_softc *sc, uint32_t off);
729 extern uint32_t ipw2200_csr_get32(struct ipw2200_softc *sc, uint32_t off);
730 extern void ipw2200_csr_getbuf32(struct ipw2200_softc *sc, uint32_t off,
731     uint32_t *buf, size_t cnt);
732 extern void ipw2200_csr_put8(struct ipw2200_softc *sc, uint32_t off,
733     uint8_t val);
734 extern void ipw2200_csr_put16(struct ipw2200_softc *sc, uint32_t off,
735     uint16_t val);
736 extern void ipw2200_csr_put32(struct ipw2200_softc *sc, uint32_t off,
737     uint32_t val);
738 /*
739  * indirect memory space access macros
740  */
741 extern uint8_t ipw2200_imem_get8(struct ipw2200_softc *sc, uint32_t addr);
742 extern uint16_t ipw2200_imem_get16(struct ipw2200_softc *sc,
743     uint32_t addr);
744 extern uint32_t ipw2200_imem_get32(struct ipw2200_softc *sc,
745     uint32_t addr);
746 extern void ipw2200_imem_put8(struct ipw2200_softc *sc, uint32_t addr,
747     uint8_t val);
748 extern void ipw2200_imem_put16(struct ipw2200_softc *sc, uint32_t addr,
749     uint16_t val);
750 extern void ipw2200_imem_put32(struct ipw2200_softc *sc, uint32_t addr,
751     uint32_t val);
752 /*
753  * EEPROM access macro
754  */
755 extern void ipw2200_rom_control(struct ipw2200_softc *sc, uint32_t val);
756 extern uint16_t ipw2200_rom_get16(struct ipw2200_softc *sc, uint8_t addr);
757 
758 /*
759  * Firmware related definations and interfaces.
760  */
761 extern int ipw2200_cache_firmware(struct ipw2200_softc *sc);
762 extern int ipw2200_free_firmware(struct ipw2200_softc *sc);
763 extern int ipw2200_load_uc(struct ipw2200_softc *sc, uint8_t *buf, size_t size);
764 extern int ipw2200_load_fw(struct ipw2200_softc *sc, uint8_t *buf, size_t size);
765 
766 #ifdef __cplusplus
767 }
768 #endif
769 
770 #endif /* _SYS_IPW2200_IMPL_H */
771