xref: /onnv-gate/usr/src/uts/common/io/pcwl/pcwl.h (revision 11101:69561cde8165)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 1997, 1998, 1999
8  *      Bill Paul <wpaul@ctr.columbia.edu>.  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, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by Bill Paul.
21  * 4. Neither the name of the author nor the names of any co-contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /*
39  * Hardware specific driver declarations for Lucent and PrismII
40  * chipsets.
41  */
42 
43 #ifndef _SYS_PCWL_H
44 #define	_SYS_PCWL_H
45 
46 #ifdef	__cplusplus
47 extern "C" {
48 #endif
49 
50 #include <sys/list.h>
51 
52 /*
53  * Encryption controls. We can enable or disable encryption as
54  * well as specify up to 4 encryption keys. We can also specify
55  * which of the four keys will be used for transmit encryption.
56  */
57 #define	WL_RID_ENCRYPTION	0xFC20
58 #define	WL_RID_ENCRYPTION_P2	0xFC28
59 #define	WL_RID_DEFLT_CRYPT_KEYS 0xFCB0
60 #define	WL_RID_CRYPT_KEY0_P2	0xFC24
61 #define	WL_RID_TX_CRYPT_KEY	0xFCB1
62 #define	WL_RID_TX_CRYPT_KEY_P2	0xFC23
63 #define	WL_RID_COMP_IDENT	0xFD20	/* version */
64 #define	WL_RID_WEP_AVAIL	0xFD4F
65 
66 #define	WL_RID_AUTHTYPE_P2	0xFC2A	/* PRISM-II */
67 #define	WL_RID_AUTHTYPE_L	0xFC21	/* 0xFC21 on Lucent */
68 #define	WL_AUTHTYPE_SYS_P2	0x1
69 #define	WL_AUTHTYPE_KEY_P2	0x2
70 #define	WL_AUTHTYPE_ALL_P2	(WL_AUTHTYPE_SYS_P2 | WL_AUTHTYPE_KEY_P2)
71 
72 #define	WL_SPEED_1Mbps_P2	0x1
73 #define	WL_SPEED_2Mbps_P2	0x2
74 #define	WL_SPEED_55Mbps_P2	0x4
75 #define	WL_SPEED_11Mbps_P2	0x8
76 
77 /*
78  * PrismII Tx rate
79  */
80 #define	WL_P_TX_RATE_FIX_1M	WL_SPEED_1Mbps_P2
81 #define	WL_P_TX_RATE_FIX_2M	WL_SPEED_2Mbps_P2
82 #define	WL_P_TX_RATE_FIX_5M	WL_SPEED_55Mbps_P2
83 #define	WL_P_TX_RATE_FIX_11M	WL_SPEED_11Mbps_P2
84 #define	WL_P_TX_RATE_AUTO_H	\
85 	(WL_SPEED_11Mbps_P2 | WL_SPEED_55Mbps_P2 | \
86 	WL_SPEED_2Mbps_P2 | WL_SPEED_1Mbps_P2)
87 #define	WL_P_TX_RATE_AUTO_M	\
88 	(WL_SPEED_55Mbps_P2 | WL_SPEED_2Mbps_P2 | \
89 	WL_SPEED_1Mbps_P2)
90 #define	WL_P_TX_RATE_AUTO_L	\
91 	(WL_SPEED_2Mbps_P2 | WL_SPEED_1Mbps_P2)
92 
93 
94 #define	WL_TIMEOUT	500000
95 
96 /*
97  * Default port: 0 (only 0 exists on stations)
98  */
99 #define	WL_DEFAULT_PORT		0
100 
101 /*
102  * Lucent TX rate: Default 11Mbps
103  */
104 #define	WL_L_TX_RATE_FIX_1M	1
105 #define	WL_L_TX_RATE_FIX_2M	2
106 #define	WL_L_TX_RATE_AUTO_H	3
107 #define	WL_L_TX_RATE_FIX_5M	4 /* 5.5M */
108 #define	WL_L_TX_RATE_FIX_11M	5
109 #define	WL_L_TX_RATE_AUTO_L	6
110 #define	WL_L_TX_RATE_AUTO_M	7
111 
112 #define	WL_TX_RATE_FIX_1M(p) \
113 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
114 	WL_P_TX_RATE_FIX_1M : WL_L_TX_RATE_FIX_1M)
115 #define	WL_TX_RATE_FIX_2M(p) \
116 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
117 	WL_P_TX_RATE_FIX_2M : WL_L_TX_RATE_FIX_2M)
118 #define	WL_TX_RATE_AUTO_H(p) \
119 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
120 	WL_P_TX_RATE_AUTO_H : WL_L_TX_RATE_AUTO_H)
121 #define	WL_TX_RATE_FIX_5M(p) \
122 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
123 	WL_P_TX_RATE_FIX_5M : WL_L_TX_RATE_FIX_5M)
124 #define	WL_TX_RATE_FIX_11M(p) \
125 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
126 	WL_P_TX_RATE_FIX_11M : WL_L_TX_RATE_FIX_11M)
127 #define	WL_TX_RATE_AUTO_L(p) \
128 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
129 	WL_P_TX_RATE_AUTO_L : WL_L_TX_RATE_AUTO_L)
130 #define	WL_TX_RATE_AUTO_M(p) \
131 	(p->pcwl_chip_type == PCWL_CHIP_PRISMII ? \
132 	WL_P_TX_RATE_AUTO_M : WL_L_TX_RATE_AUTO_M)
133 
134 /*
135  * Default network name: empty string implies any
136  */
137 #define	WL_DEFAULT_NETNAME	("")
138 #define	WL_DEFAULT_NODENAME	("solaris node")
139 #define	WL_DEFAULT_AP_DENSITY	1
140 #define	WL_DEFAULT_RTS_THRESH	2347
141 #define	WL_DEFAULT_DATALEN	2304
142 #define	WL_DEFAULT_CREATE_IBSS	0
143 #define	WL_DEFAULT_PM_ENABLED	0
144 #define	WL_DEFAULT_MAX_SLEEP	100
145 #define	WL_DEFAULT_CHAN		3
146 #define	WL_DEFAULT_TX_CRYPT_KEY	0
147 
148 /*
149  * Size of Hermes I/O space.
150  */
151 #define	WL_IOSIZ	0x40
152 
153 /*
154  * Hermes command/status registers.
155  */
156 #define	WL_COMMAND	0x00
157 #define	WL_PARAM0	0x02
158 #define	WL_PARAM1	0x04
159 #define	WL_PARAM2	0x06
160 #define	WL_STATUS	0x08
161 #define	WL_RESP0	0x0A
162 #define	WL_RESP1	0x0C
163 #define	WL_RESP2	0x0E
164 
165 /*
166  * Command register values.
167  */
168 #define	WL_CMD_BUSY		0x8000 /* busy bit */
169 #define	WL_CMD_INI		0x0000 /* initialize */
170 #define	WL_CMD_ENABLE		0x0001 /* enable */
171 #define	WL_CMD_DISABLE		0x0002 /* disable */
172 #define	WL_CMD_DIAG		0x0003
173 #define	WL_CMD_ALLOC_MEM	0x000A /* allocate NIC memory */
174 #define	WL_CMD_TX		0x000B /* transmit */
175 #define	WL_CMD_NOTIFY		0x0010
176 #define	WL_CMD_INQUIRE		0x0011
177 #define	WL_CMD_ACCESS		0x0021
178 #define	WL_CMD_PROGRAM		0x0022
179 
180 #define	WL_CMD_CODE_MASK	0x003F
181 
182 /*
183  * Reclaim qualifier bit, applicable to the
184  * TX and INQUIRE commands.
185  */
186 #define	WL_RECLAIM		0x0100 /* reclaim NIC memory */
187 
188 /*
189  * ACCESS command qualifier bits.
190  */
191 #define	WL_ACCESS_READ		0x0000
192 #define	WL_ACCESS_WRITE		0x0100
193 
194 /*
195  * PROGRAM command qualifier bits.
196  */
197 #define	WL_PROGRAM_DISABLE	0x0000
198 #define	WL_PROGRAM_ENABLE_RAM	0x0100
199 #define	WL_PROGRAM_ENABLE_NVRAM	0x0200
200 #define	WL_PROGRAM_NVRAM	0x0300
201 
202 /*
203  * Status register values
204  */
205 #define	WL_STAT_CMD_CODE	0x003F
206 #define	WL_STAT_DIAG_ERR	0x0100
207 #define	WL_STAT_INQ_ERR		0x0500
208 #define	WL_STAT_CMD_RESULT	0x7F00
209 
210 /*
211  * memory handle management registers
212  */
213 #define	WL_INFO_FID		0x10
214 #define	WL_RX_FID		0x20
215 #define	WL_ALLOC_FID		0x22
216 #define	WL_TX_CMP_FID		0x24
217 
218 #define	WL_INVALID_FID		0xffff
219 
220 /*
221  * Buffer Access Path (BAP) registers.
222  * These are I/O channels.  you can use each one for
223  * any desired purpose independently of the other. In general
224  * though, we use BAP1 for reading and writing LTV records and
225  * reading received data frames, and BAP0 for writing transmit
226  * frames. This is a convention though, not a rule.
227  * For PrismII chip, frequently overlap between BAP0 and BAP1
228  * may hang the hardware. this is a known bug, so just use BAP1
229  * for PrismII.
230  */
231 #define	WL_SEL0			0x18
232 #define	WL_SEL1			0x1A
233 #define	WL_OFF0			0x1C
234 #define	WL_OFF1			0x1E
235 #define	WL_DATA0		0x36
236 #define	WL_DATA1		0x38
237 #define	WL_BAP0			WL_DATA0
238 #define	WL_BAP1			WL_DATA1
239 
240 #define	WL_OFF_BUSY		0x8000
241 #define	WL_OFF_ERR		0x4000
242 #define	WL_OFF_DATAOFF		0x0FFF
243 
244 /*
245  * Event registers
246  */
247 #define	WL_EVENT_STAT		0x30	/* Event status */
248 #define	WL_INT_EN		0x32	/* Interrupt enable/disable */
249 #define	WL_EVENT_ACK		0x34	/* Ack event */
250 
251 /*
252  * Events
253  */
254 #define	WL_EV_TICK		0x8000	/* aux timer tick */
255 #define	WL_EV_RES		0x4000	/* controller h/w error (time out) */
256 #define	WL_EV_INFO_DROP		0x2000	/* no RAM to build unsolicited frame */
257 #define	WL_EV_NO_CARD		0x0800	/* card removed (hunh?) */
258 #define	WL_EV_DUIF_RX		0x0400	/* wavelan management packet received */
259 #define	WL_EV_INFO		0x0080	/* async info frame */
260 #define	WL_EV_CMD		0x0010	/* command completed */
261 #define	WL_EV_ALLOC		0x0008	/* async alloc/reclaim completed */
262 #define	WL_EV_TX_EXC		0x0004	/* async xmit completed with failure */
263 #define	WL_EV_TX		0x0002	/* async xmit completed succesfully */
264 #define	WL_EV_RX		0x0001	/* async rx completed */
265 
266 #define	WL_EV_ALL		0xffff	/* all events */
267 #define	WL_INTRS	\
268 	(WL_EV_RX|WL_EV_TX|WL_EV_TX_EXC|WL_EV_ALLOC|WL_EV_INFO|WL_EV_INFO_DROP)
269 
270 /*
271  * Host software registers
272  */
273 #define	WL_SW0			0x28
274 #define	WL_SW1			0x2A
275 #define	WL_SW2			0x2C
276 #define	WL_SW3			0x2E
277 
278 #define	WL_CNTL			0x14
279 
280 #define	WL_CNTL_AUX_ENA		0xC000
281 #define	WL_CNTL_AUX_ENA_STAT	0xC000
282 #define	WL_CNTL_AUX_DIS_STAT	0x0000
283 #define	WL_CNTL_AUX_ENA_CNTL	0x8000
284 #define	WL_CNTL_AUX_DIS_CNTL	0x4000
285 
286 #define	WL_AUX_PAGE		0x3A
287 #define	WL_AUX_OFFSET		0x3C
288 #define	WL_AUX_DATA		0x3E
289 
290 #define	WL_RID_DNLD_BUF		0xFD01
291 
292 /*
293  * Mem sizes (0xFD02).
294  */
295 #define	WL_RID_MEMSZ		0xFD02
296 #define	WL_RID_FWIDENT_P2	0xFD02
297 
298 /*
299  * NIC Identification (0xFD0B).
300  */
301 #define	WL_RID_CARD_ID	0xFD0B
302 
303 typedef struct pcwl_ltv_ver {
304 	uint16_t	wl_compid;
305 	uint16_t	wl_variant;
306 	uint16_t	wl_major;
307 	uint16_t	wl_minor;
308 } pcwl_ltv_ver_t;
309 
310 #define	WL_RID_FWVER	0xFFFF
311 typedef struct pcwl_ltv_fwver {
312 	uint16_t	pri[7];
313 	uint16_t	st[7];
314 } pcwl_ltv_fwver_t;
315 
316 #define	WI_NIC_EVB2	0x8000
317 #define	WI_NIC_HWB3763	0x8001
318 #define	WI_NIC_HWB3163	0x8002
319 #define	WI_NIC_HWB3163B	0x8003
320 #define	WI_NIC_EVB3	0x8004
321 #define	WI_NIC_HWB1153	0x8007
322 #define	WI_NIC_P2_SST	0x8008	/* Prism2 with SST flush */
323 #define	WI_NIC_PRISM2_5	0x800C
324 #define	WI_NIC_3874A	0x8013	/* Prism2.5 Mini-PCI */
325 
326 /*
327  * List of intended regulatory domains (0xFD11).
328  */
329 #define	WL_RID_DOMAINS		0xFD11
330 /*
331  * CIS struct (0xFD13).
332  */
333 #define	WL_RID_CIS		0xFD13
334 
335 /*
336  * Current MAC port connection status
337  */
338 #define	WL_RID_PORTSTATUS	0xFD40
339 #define	WL_PORT_DISABLED	1
340 #define	WL_PORT_INITIAL		2
341 #define	WL_PORT_TO_IBSS		3
342 #define	WL_PORT_TO_BSS		4
343 #define	WL_PORT_OOR		5
344 #define	WL_PORT_RADIO_OFF	7 /* only for miniPci */
345 
346 /*
347  * Current Service Set the station is connected to
348  */
349 #define	WL_RID_SSID		0xFD41
350 
351 /*
352  * MAC address used as identifier of the BSS the station
353  * is connected to
354  */
355 #define	WL_RID_BSSID		0xFD42
356 
357 /*
358  * Communications quality (0xFD43).
359  */
360 #define	WL_RID_COMMQUAL		0xFD43
361 
362 /*
363  * Actual system scale thresholds (0xFD46).
364  */
365 #define	WL_RID_SYSTEM_SCALE	0xFC06
366 
367 /*
368  * Actual current transmission rate
369  */
370 #define	WL_RID_CUR_TX_RATE	0xFD44
371 
372 /*
373  * Connection control characteristics.
374  * 1 == Basic Service Set (BSS), a.k.a IEEE 802.11 Infrastructure
375  * 2 == Wireless Distribudion System (WDS), Access Point only
376  * 3 == Pseudo IBSS / Ad Hoc
377  */
378 #define	WL_RID_PORTTYPE		0xFC00
379 #define	WL_PORTTYPE_BSS		0x1
380 #define	WL_PORTTYPE_WDS		0x2
381 #define	WL_PORTTYPE_ADHOC	0x3
382 
383 /*
384  * Mac addresses.
385  */
386 #define	WL_RID_MAC_NODE		0xFC01
387 #define	WL_RID_MAC_WDS		0xFC08
388 
389 /*
390  * Station set identification (SSID).
391  */
392 #define	WL_RID_DESIRED_SSID	0xFC02
393 #define	WL_RID_OWN_SSID		0xFC04
394 
395 /*
396  * Set communications channel (radio frequency).
397  */
398 #define	WL_RID_OWN_CHNL		0xFC03
399 #define	WL_RID_CURRENT_CHNL	0xFDC1
400 
401 /*
402  * Frame data size.
403  */
404 #define	WL_RID_MAX_DATALEN	0xFC07
405 
406 /*
407  * ESS power management enable
408  */
409 #define	WL_RID_PM_ENABLED	0xFC09
410 
411 /*
412  * ESS max PM sleep internal
413  */
414 #define	WL_RID_MAX_SLEEP	0xFC0C
415 
416 /*
417  * Set our station name.
418  */
419 #define	WL_RID_NODENAME		0xFC0E
420 
421 /*
422  * Multicast addresses to be put in filter. We're
423  * allowed up to 16 addresses in the filter.
424  */
425 #define	WL_RID_MCAST		0xFC80
426 
427 /*
428  * Create IBSS.
429  */
430 #define	WL_RID_CREATE_IBSS	0xFC81
431 
432 #define	WL_RID_FRAG_THRESH	0xFC82
433 #define	WL_RID_RTS_THRESH	0xFC83
434 
435 /*
436  * TX rate control
437  * 0 == Fixed 1mbps
438  * 1 == Fixed 2mbps
439  * 2 == auto fallback
440  */
441 #define	WL_RID_TX_RATE		0xFC84
442 
443 /*
444  * promiscuous mode.
445  */
446 #define	WL_RID_PROMISC		0xFC85
447 
448 /*
449  * scan ssid
450  */
451 #define	WL_RID_SCAN_SSID	0xFCB2
452 
453 /*
454  * Auxiliary Timer tick interval
455  */
456 #define	WL_RID_TICK_TIME	0xFCE0
457 
458 /*
459  * PrismII scan
460  */
461 #define	WL_RID_SCAN_REQUEST	0xFCE1
462 #define	WL_RID_HSCAN_REQUEST	0xFCE5
463 
464 /*
465  * Information frame types.
466  */
467 #define	WL_INFO_NOTIFY		0xF000	/* Handover address */
468 #define	WL_INFO_COUNTERS	0xF100	/* Statistics counters */
469 #define	WL_INFO_SCAN_RESULTS	0xF101	/* Scan results */
470 #define	WL_INFO_HSCAN_RESULTS	0xF103	/* HostScan results */
471 #define	WL_INFO_LINK_STAT	0xF200	/* Link status */
472 #define	WL_INFO_ASSOC_STAT	0xF201	/* Association status */
473 
474 /*
475  * Link status
476  */
477 #define	WL_LINK_CONNECT		1
478 #define	WL_LINK_DISCONNECT	2
479 #define	WL_LINK_AP_CR		3 /* AP change */
480 #define	WL_LINK_AP_OOR		4 /* AP out of range */
481 #define	WL_LINK_AP_IR		5 /* AP in range */
482 
483 typedef struct wl_scan_result {
484 	uint16_t		wl_srt_chid;  /* bss channel id */
485 	uint16_t		wl_srt_anl;   /* noise level */
486 	uint16_t		wl_srt_sl;    /* signal level */
487 	uint8_t			wl_srt_bssid[6];  /* mac address of the bss */
488 	uint16_t		wl_srt_bcnint; /* bss beacon interval */
489 	uint16_t		wl_srt_cap;    /* bss capability */
490 
491 	uint16_t		wl_srt_ssidlen;  /* ssid name length */
492 	char			wl_srt_ssid[32]; /* ssid */
493 
494 	uint16_t		wl_srt_suprates[5]; /* supported rates */
495 	uint16_t		wl_srt_rate; /* actual data rate of the probe */
496 	uint16_t		wl_srt_atim;
497 } wl_scan_result_t;
498 
499 #define	WL_SRT_MAX_NUM		32 /* max number of scan result stored */
500 #define	WL_SCAN_TIMEOUT_MAX	30 /* seconds after which the scan item ages */
501 #define	WL_SCAN_AGAIN_THRESHOLD	5 /* threshold below which card scan again */
502 #define	WL_MAX_SCAN_TIMES	2 /* max scan times per scan command */
503 
504 typedef struct wl_scan_list {
505 	wl_scan_result_t	wl_val;
506 	uint32_t		wl_timeout;
507 	list_node_t		wl_scan_node;
508 } wl_scan_list_t;
509 
510 #define	WL_FTYPE_MGMT		0x0000
511 #define	WL_FTYPE_CTL		0x0004
512 #define	WL_FTYPE_DATA		0x0008
513 
514 /*
515  * SNAP (sub-network access protocol) constants for transmission
516  * of IP datagrams over IEEE 802 networks, taken from RFC1042.
517  * We need these for the LLC/SNAP header fields in the TX/RX frame
518  * structure.
519  */
520 #define	WL_SNAP_K1		0xaa	/* assigned global SAP for SNAP */
521 #define	WL_SNAP_K2		0x00
522 #define	WL_SNAP_CONTROL		0x03	/* unnumbered information format */
523 #define	WL_SNAP_WORD0		(WL_SNAP_K1 | (WL_SNAP_K1 << 8))
524 #define	WL_SNAP_WORD1		(WL_SNAP_K2 | (WL_SNAP_CONTROL << 8))
525 #define	WL_SNAPHDR_LEN		0x6
526 
527 /*
528  * Hermes transmit/receive frame structure
529  */
530 typedef struct wl_frame {
531 	uint16_t		wl_status;	/* 0x00 */
532 	uint16_t		wl_rsvd0;	/* 0x02 */
533 	uint16_t		wl_rsvd1;	/* 0x04 */
534 	uint16_t		wl_q_info;	/* 0x06 */
535 	uint16_t		wl_rsvd2;	/* 0x08 */
536 	uint16_t		wl_rsvd3;	/* 0x0A */
537 	uint16_t		wl_tx_ctl;	/* 0x0C */
538 	uint16_t		wl_frame_ctl;	/* 0x0E */
539 	uint16_t		wl_id;		/* 0x10 */
540 	uint8_t			wl_addr1[6];	/* 0x12 */
541 	uint8_t			wl_addr2[6];	/* 0x18 */
542 	uint8_t			wl_addr3[6];	/* 0x1E */
543 	uint16_t		wl_seq_ctl;	/* 0x24 */
544 	uint8_t			wl_addr4[6];	/* 0x26 */
545 	uint16_t		wl_dat_len;	/* 0x2C */
546 
547 	uint8_t			wl_dst_addr[6];	/* 0x2E */
548 	uint8_t			wl_src_addr[6];	/* 0x34 */
549 	uint16_t		wl_len;		/* 0x3A */
550 	uint16_t		wl_dat[3];	/* 0x3C */ /* SNAP header */
551 	uint16_t		wl_type;	/* 0x42 */
552 } wl_frame_t;
553 
554 static wl_frame_t wl_frame_default = {
555 	0,			/* wl_status	   0x00 */
556 	0,			/* wl_rsvd0	   0x02 */
557 	0,			/* wl_rsvd1	   0x04 */
558 	0,			/* wl_q_info	   0x06 */
559 	0,			/* wl_rsvd2	   0x08 */
560 	0,			/* wl_rsvd3	   0x0A */
561 	0,			/* wl_tx_ctl	   0x0C */
562 	WL_FTYPE_DATA,		/* wl_frame_ctl	   0x0E */
563 	0,			/* wl_id	   0x10 */
564 	{ 0, 0, 0, 0, 0, 0 },	/* wl_addr1[6]	   0x12 */
565 	{ 0, 0, 0, 0, 0, 0 },	/* wl_addr2[6]	   0x18 */
566 	{ 0, 0, 0, 0, 0, 0 },	/* wl_addr3[6]	   0x1E */
567 	0,			/* wl_seq_ctl	   0x24 */
568 	{ 0, 0, 0, 0, 0, 0 },	/* wl_addr4[6]	   0x26 */
569 	(uint16_t)-WL_SNAPHDR_LEN, /* wl_dat_len	   0x2C */
570 
571 	{ 0, 0, 0, 0, 0, 0 },	/* wl_dst_addr[6]  0x2E */
572 	{ 0, 0, 0, 0, 0, 0 },	/* wl_src_addr[6]  0x34 */
573 	(uint16_t)-WL_SNAPHDR_LEN, /* wl_len	   0x3A */
574 	{ WL_SNAP_WORD0,
575 	WL_SNAP_WORD1, 0 },	/* wl_dat[3]	   0x3C */ /* SNAP header */
576 	0			/* wl_type	   0x42 */
577 };
578 
579 #define	MLEN(mp)		((mp)->b_wptr - (mp)->b_rptr)
580 #define	ETH_HDRLEN		(sizeof (struct ether_header))
581 #define	WL_802_3_HDRLEN		0x2E
582 #define	WL_802_11_HDRLEN	0x44
583 #define	WL_802_11_RAW_HDRLEN	0x3C
584 
585 #define	WL_STAT_BADCRC		0x0001
586 #define	WL_STAT_UNDECRYPTABLE	0x0002
587 #define	WL_STAT_ERRSTAT		0x0003
588 #define	WL_STAT_MAC_PORT	0x0700
589 #define	WL_STAT_1042		0x2000	/* RFC1042 encoded */
590 #define	WL_STAT_TUNNEL		0x4000	/* Bridge-tunnel encoded */
591 #define	WL_STAT_WMP_MSG		0x6000	/* WaveLAN-II management protocol */
592 #define	WL_RXSTAT_MSG_TYPE	0xE000
593 
594 #define	WL_ENC_TX_802_3		0x00
595 #define	WL_ENC_TX_802_11	0x11
596 #define	WL_ENC_TX_E_II		0x0E
597 
598 #define	WL_ENC_TX_1042		0x00
599 #define	WL_ENC_TX_TUNNEL	0xF8
600 
601 #define	WL_TXCNTL_MACPORT	0x00FF
602 #define	WL_TXCNTL_STRUCTTYPE	0xFF00
603 #define	WL_TXCNTL_TXOK		0x2
604 #define	WL_TXCNTL_TXEX		0x4
605 #define	WL_TXCNTL_SET	(WL_TXCNTL_TXOK | WL_TXCNTL_TXEX)
606 
607 typedef struct rf_ckey {
608 	uint16_t	ckey_len;
609 	uint8_t		ckey_dat[14];
610 } rf_ckey_t;
611 
612 /*
613  * Configurable parameters of the RF interface
614  * All the info here is passed to the card through PIO.
615  */
616 typedef struct pcwl_rf {
617 	uint16_t	rf_max_datalen;
618 	uint16_t	rf_create_ibss;
619 	uint16_t	rf_porttype;
620 	uint16_t	rf_rts_thresh;
621 	uint16_t	rf_tx_rate;
622 	uint16_t	rf_system_scale;
623 	uint16_t	rf_pm_enabled;
624 	uint16_t	rf_max_sleep;
625 	uint16_t	rf_own_chnl;
626 	uint16_t	rf_port_no;
627 	char		rf_own_ssid[34];
628 	char		rf_desired_ssid[34];
629 	char		rf_nodename[34];
630 	uint16_t	rf_promiscuous;
631 	uint16_t	rf_encryption;		/* use encryption? */
632 	uint16_t	rf_authtype;		/* prism2 only */
633 	uint16_t	rf_tx_crypt_key;
634 	rf_ckey_t	rf_ckeys[4];
635 } pcwl_rf_t;
636 
637 #define	PCWL_MCAST_ENTSHIFT	4
638 #define	PCWL_MCAST_ENTRIES	(1 << PCWL_MCAST_ENTSHIFT)
639 #define	PCWL_MCBUF_LEN		(ETHERADDRL << PCWL_MCAST_ENTSHIFT)
640 #define	PCWL_MCBUF_WORDS	(PCWL_MCBUF_LEN >> 1)
641 
642 typedef enum {
643 	WLC_TX_UNICAST_FRAMES,		/*  0+ */
644 	WLC_TX_MULTICAST_FRAMES,	/*  1+ */
645 	WLC_TX_FRAGMENTS,		/*  2+ */
646 	WLC_TX_UNICAST_OCTETS,		/*  3+ */
647 	WLC_TX_MULTICAST_OCTETS,	/*  4  */
648 	WLC_TX_DEFERRED_XMITS,		/*  5+ */
649 	WLC_TX_SINGLE_RETRIES,		/*  6+ */
650 	WLC_TX_MULTI_RETRIES,		/*  7+ */
651 	WLC_TX_RETRY_LIMIT,		/*  8+ */
652 	WLC_TX_DISCARDS,		/*  9+ */
653 	WLC_RX_UNICAST_FRAMES,		/* 10+ */
654 	WLC_RX_MULTICAST_FRAMES,	/* 11+ */
655 	WLC_RX_FRAGMENTS,		/* 12+ */
656 	WLC_RX_UNICAST_OCTETS,		/* 13+ */
657 	WLC_RX_MULTICAST_OCTETS,	/* 14  */
658 	WLC_RX_FCS_ERRORS,		/* 15+ */
659 	WLC_RX_DISCARDS_NOBUF,		/* 16+ */
660 	WLC_TX_DISCARDS_WRONG_SA,	/* 17+ */
661 	WLC_RX_WEP_CANT_DECRYPT,	/* 18+ */
662 	WLC_RX_MSG_IN_MSG_FRAGS,	/* 19+ */
663 	WLC_RX_MSG_IN_BAD_MSG_FRAGS,	/* 20+ */
664 	WLC_STAT_CNT			/* 21 - keep it as the last entry */
665 } pcwl_cntr_offset;
666 
667 #define	WL_XMT_BUF_NUM	8
668 typedef struct	wl_tx_ring_data {
669 	uint16_t		wl_tx_fids[WL_XMT_BUF_NUM];
670 	uint16_t		wl_tx_ring[WL_XMT_BUF_NUM];
671 	int			wl_tx_prod;
672 	int			wl_tx_cons;
673 	kmutex_t		wl_tx_lock;	/* for send only */
674 } pcwl_txring_t;
675 
676 #define	PCWL_DEVICE_PCI		0
677 #define	PCWL_DEVICE_PCCARD	1
678 
679 /*
680  * The macinfo is really used as the softstate structure.
681  *
682  * pcwl_mh	 - mac_handle_t structure
683  * pcwl_cslock	 - lock for card services request. Used with pcwl_cscv
684  * pcwl_cscv	 - condition variable to wait for card events
685  * pcwl_chdl	 - client handle, an uint32_t bit mask encoding for socket,
686  *			function, and client info.
687  *			See cs_priv.h MAKE_CLIENT_HANDLE.
688  * pcwl_log_sock - holds the logical to physical translation for this card.
689  *			Specifically has physical adapter and socket #.
690  *			Socket # is the same as part of the pcwl_chdl encoding.
691  *			Physical adapter # is from card service socket impl.
692  */
693 typedef struct pcwl_macinfo {
694 	mac_handle_t		pcwl_mh;
695 	dev_info_t		*pcwl_dip;
696 	int			pcwl_device_type; /* pci or pcmcia card */
697 	kmutex_t		pcwl_cslock;	/* for card services */
698 	kcondvar_t		pcwl_cscv;	/* for card services */
699 	client_handle_t		pcwl_chdl;	/* s,f,c encoding, cs_priv.h */
700 	map_log_socket_t	pcwl_log_sock;	/* logical/phys socket map */
701 
702 	int			pcwl_socket;    /* socket number */
703 	int			pcwl_config_hi;	/* cfttbl index */
704 	int			pcwl_config;	/* default config index */
705 	int			pcwl_vcc;	/* vcc level */
706 	int			pcwl_iodecode;	/* # of address lines */
707 	int			pcwl_chip_type;	/* Lucent or Prism-II */
708 
709 	uint8_t 		pcwl_mac_addr[ETHERADDRL];
710 	uint8_t 		pcwl_bssid[ETHERADDRL];
711 	uint16_t		pcwl_has_wep;	/* has encryption capability */
712 	uint32_t		pcwl_flag;
713 	uint32_t		pcwl_reschedule_need;
714 	pcwl_rf_t		pcwl_rf;	/* RF interface parameters */
715 
716 	uint16_t		pcwl_dmem_id;	/* nic mem id for tx buffer */
717 	uint16_t		pcwl_mgmt_id;	/* nic mem id for mgmt buffer */
718 	pcwl_txring_t		pcwl_txring;
719 
720 	uint16_t		pcwl_mcast[PCWL_MCBUF_WORDS]; /* MC filters */
721 
722 	kmutex_t		pcwl_scanlist_lock;	/* scanlist lock */
723 	kmutex_t		pcwl_glock;	/* generic lock */
724 
725 	caddr_t			pcwl_bar;	/* for pci device only */
726 	ddi_acc_handle_t	pcwl_handle;
727 	caddr_t			pcwl_cfg_base;
728 	ddi_acc_handle_t	pcwl_cfg_handle;
729 
730 	ddi_acc_handle_t	pcwl_port;	/* for pcmcia device only */
731 
732 	ddi_iblock_cookie_t	pcwl_ib_cookie;
733 	ddi_softintr_t		pcwl_softint_id; /* pcwl_intr soft intr id */
734 
735 	uint16_t		pcwl_cntrs_t[WLC_STAT_CNT];
736 	uint64_t		pcwl_cntrs_s[WLC_STAT_CNT];
737 	uint64_t		pcwl_noxmtbuf;
738 	timeout_id_t		pcwl_scanlist_timeout_id;
739 	list_t			pcwl_scan_list;
740 	uint16_t		pcwl_scan_num;
741 	uint16_t		pcwl_rssi;
742 	timeout_id_t		pcwl_connect_timeout_id;
743 } pcwl_maci_t;
744 
745 #define	PCWL_IDENT_STRING	modldrv.drv_linkinfo
746 #define	PCWL_CHIP_LUCENT	0
747 #define	PCWL_CHIP_PRISMII	1
748 #define	HDL(pcwl_p)		((pcwl_p)->pcwl_port)
749 #define	GLD3(pcwl_p)		((pcwl_p)->pcwl_mh)
750 #define	DIP(pcwl_p)		((pcwl_p)->pcwl_dip)
751 #define	RF(pcwl_p)		(&(pcwl_p)->pcwl_rf)
752 
753 #define	PCWL_CARD_INTREN	0x1
754 #define	PCWL_SOFTINTR		0x2	/* high level and soft intr enabled */
755 #define	PCWL_CARD_LINKUP	0x4	/* link status of the STA */
756 #define	PCWL_CARD_GSTAT		0x8
757 #define	PCWL_ATTACHED		0x10
758 #define	PCWL_CS_REGISTERED	0x20
759 #define	PCWL_ENABLED		0x40
760 #define	PCWL_CARD_READY		0x80
761 #define	PCWL_CARD_FAILED	0x100
762 #define	PCWL_CARD_INTR		0x200
763 #define	PCWL_CARD_PLUMBED	0x400
764 #define	PCWL_CARD_SUSPEND	0x800
765 
766 #define	PCWL_STATE_IDLE		0x1
767 
768 #define	PCWL_NICMEM_SZ		(2048) /* 80211MTU set as 1500, so 2k here */
769 
770 static int	pcwl_probe(dev_info_t *dip);
771 static int	pcwl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
772 static int	pcwl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
773 
774 static int	pcwl_register_cs(dev_info_t *dip, pcwl_maci_t *pcwl_p);
775 static void	pcwl_unregister_cs(pcwl_maci_t *pcwl_p);
776 static void	pcwl_destroy_locks(pcwl_maci_t *pcwl_p);
777 static int	pcwl_reset_backend(pcwl_maci_t *pcwl_p);
778 static int	pcwl_get_cap(pcwl_maci_t *pcwl_p);
779 static int	pcwl_card_insert(pcwl_maci_t *pcwl_p);
780 static int	pcwl_ev_hdlr(event_t ev, int pri, event_callback_args_t *arg);
781 static void	pcwl_card_remove(pcwl_maci_t *pcwl_p);
782 static int	pcwl_init_nicmem(pcwl_maci_t *pcwl_p);
783 
784 /*
785  * high level device access primitives, glock must held before calling
786  */
787 static uint16_t	pcwl_set_cmd(pcwl_maci_t *pcwl_p, uint16_t mode, uint16_t type);
788 static uint16_t pcwl_set_ch(pcwl_maci_t *, uint16_t, uint16_t, uint16_t);
789 static uint16_t	pcwl_get_ltv(pcwl_maci_t *pcwl_p, uint16_t len, uint16_t type,
790 			uint16_t *val_p);
791 static uint16_t	pcwl_put_ltv(pcwl_maci_t *pcwl_p, uint16_t len, uint16_t type,
792 			uint16_t *val_p);
793 static uint16_t	pcwl_fil_ltv(pcwl_maci_t *pcwl_p, uint16_t len, uint16_t type,
794 			uint16_t val);
795 static uint16_t	pcwl_put_str(pcwl_maci_t *pcwl_p, uint16_t type, char *str_p);
796 static uint16_t pcwl_rdch0(pcwl_maci_t *pcwl_p, uint16_t type, uint16_t off,
797 			uint16_t *buf_p, int len, int order);
798 static uint16_t pcwl_wrch1(pcwl_maci_t *pcwl_p, uint16_t type, uint16_t off,
799 			uint16_t *buf_p, int len, int order);
800 static int	pcwl_config_rf(pcwl_maci_t *pcwl_p);
801 static int	pcwl_loaddef_rf(pcwl_maci_t *pcwl_p);
802 static void	pcwl_start_locked(pcwl_maci_t *pcwl_p);
803 static void	pcwl_stop_locked(pcwl_maci_t *pcwl_p);
804 static int	pcwl_saddr_locked(pcwl_maci_t *pcwl_p);
805 static uint16_t	pcwl_alloc_nicmem(pcwl_maci_t *pcwl_p, uint16_t len,
806 			uint16_t *id_p);
807 static void	pcwl_chip_type(pcwl_maci_t *pcwl_p);
808 
809 /*
810  * Required driver entry points for mac
811  */
812 static int	pcwl_start(void *);
813 static void	pcwl_stop(void *);
814 static int	pcwl_saddr(void *, const uint8_t *);
815 static mblk_t	*pcwl_tx(void *, mblk_t *);
816 static int	pcwl_send(pcwl_maci_t *, mblk_t *);
817 static int	pcwl_prom(void *, boolean_t);
818 static int	pcwl_gstat(void *, uint_t, uint64_t *);
819 static int	pcwl_sdmulti(void *, boolean_t, const uint8_t *);
820 static void 	pcwl_ioctl(void *, queue_t *, mblk_t *);
821 
822 static uint_t	pcwl_intr(caddr_t arg);
823 static uint_t	pcwl_intr_hi(caddr_t arg);
824 static void	pcwl_rcv(pcwl_maci_t *pcwl_p);
825 static uint32_t pcwl_txdone(pcwl_maci_t *pcwl_p);
826 static void pcwl_infodone(pcwl_maci_t *pcwl_p);
827 static void 	pcwl_ssid_scan(pcwl_maci_t *, uint16_t, uint16_t, uint16_t);
828 
829 /*
830  * prototypes of the function for wifi ioctl
831  */
832 static int	pcwl_cfg_essid(mblk_t *, pcwl_maci_t *, uint32_t);
833 static int	pcwl_cfg_bssid(mblk_t *, pcwl_maci_t *, uint32_t);
834 static int	pcwl_cfg_scan(mblk_t *, pcwl_maci_t *, uint32_t);
835 static int	pcwl_cfg_linkstatus(mblk_t *, pcwl_maci_t *, uint32_t);
836 static int	pcwl_cfg_bsstype(mblk_t *, pcwl_maci_t *, uint32_t);
837 static int	pcwl_cfg_phy(mblk_t *, pcwl_maci_t *, uint32_t);
838 static int	pcwl_cfg_desiredrates(mblk_t *, pcwl_maci_t *, uint32_t);
839 static int	pcwl_cfg_supportrates(mblk_t *, pcwl_maci_t *, uint32_t);
840 static int	pcwl_cfg_powermode(mblk_t *, pcwl_maci_t *, uint32_t);
841 static int	pcwl_cfg_authmode(mblk_t *, pcwl_maci_t *, uint32_t);
842 static int	pcwl_cfg_encryption(mblk_t *, pcwl_maci_t *, uint32_t);
843 static int	pcwl_cfg_wepkeyid(mblk_t *, pcwl_maci_t *, uint32_t);
844 static int	pcwl_cfg_createibss(mblk_t *, pcwl_maci_t *, uint32_t);
845 static int	pcwl_cfg_rssi(mblk_t *, pcwl_maci_t *, uint32_t);
846 static int	pcwl_cfg_radio(mblk_t *, pcwl_maci_t *, uint32_t);
847 static int	pcwl_cfg_wepkey(mblk_t *, pcwl_maci_t *, uint32_t);
848 static void	pcwl_wlan_ioctl(pcwl_maci_t *, queue_t *, mblk_t *, uint32_t);
849 static int	pcwl_getset(mblk_t *, pcwl_maci_t *, uint32_t);
850 
851 static void	pcwl_scanlist_timeout(void *);
852 static void	pcwl_delete_scan_item(pcwl_maci_t *, wl_scan_list_t *);
853 static int	pcwl_add_scan_item(pcwl_maci_t *, wl_scan_result_t);
854 static void	pcwl_get_rssi(pcwl_maci_t *);
855 static void 	pcwl_connect_timeout(void *arg);
856 
857 #define	RDCH0(h, t, o, b_p, l)	pcwl_rdch0(h, t, o, b_p, l, 1)
858 #define	WRCH1(h, t, o, b_p, l)	pcwl_wrch1(h, t, o, b_p, l, 1)
859 #define	RDPKT(h, t, o, b_p, l)	pcwl_rdch0(h, t, o, b_p, l, 0)
860 #define	WRPKT(h, t, o, b_p, l)	pcwl_wrch1(h, t, o, b_p, l, 0)
861 
862 #define	FIL_LTV(pcwl_p, len, type, val)	 \
863 	(void) pcwl_fil_ltv(pcwl_p, len, type, val)
864 #define	PUT_LTV(pcwl_p, len, type, v_p)	 \
865 	(void) pcwl_put_ltv(pcwl_p, len, type, v_p)
866 #define	PUT_STR(pcwl_p, type, str_p)	\
867 	(void) pcwl_put_str(pcwl_p, type, str_p)
868 
869 #define	PCWL_READ(p, o, v)	{ \
870 	if (p->pcwl_device_type == PCWL_DEVICE_PCI) { \
871 		uint16_t t = ddi_get16(p->pcwl_handle, \
872 		    (uint16_t *)(p->pcwl_bar + 2*(o))); \
873 		v = LE_16(t); \
874 	} else { \
875 		uint16_t t = csx_Get16(HDL(p), o); \
876 		v = LE_16(t); \
877 	}\
878 }
879 #define	PCWL_WRITE(p, o, v)	{ \
880 	if (p->pcwl_device_type == PCWL_DEVICE_PCI) { \
881 		ddi_put16(p->pcwl_handle, \
882 		    (uint16_t *)(p->pcwl_bar + 2*(o)), LE_16(v)); \
883 	} else { \
884 		csx_Put16(HDL(p), o, LE_16(v)); \
885 	}\
886 }
887 #define	PCWL_READ_P(p, o, v, h)	{ \
888 	if (p->pcwl_device_type == PCWL_DEVICE_PCI) { \
889 		uint16_t t = ddi_get16(p->pcwl_handle, \
890 		    (uint16_t *)(p->pcwl_bar + 2*(o))); \
891 		*(v) = h ? LE_16(t) : t; \
892 	} else { \
893 		uint16_t t = csx_Get16(HDL(p), o); \
894 		*(v) = h ? LE_16(t) : t; \
895 	}\
896 }
897 #define	PCWL_WRITE_P(p, o, v, h)	{ \
898 	if (p->pcwl_device_type == PCWL_DEVICE_PCI) { \
899 		ddi_put16(p->pcwl_handle, (uint16_t *)(p->pcwl_bar + 2*(o)), \
900 		    h ? LE_16(*(v)) : (*(v))); \
901 	} else {\
902 		csx_Put16(HDL(p), o, h ? LE_16(*(v)) : (*(v))); \
903 	}\
904 }
905 
906 #ifdef _BIG_ENDIAN
907 #define	PCWL_SWAP16(buf_p, len) { \
908 	int pcwl_swap_len = len; \
909 	for (pcwl_swap_len = (pcwl_swap_len + 1) >> 1; pcwl_swap_len; ) { \
910 		uint16_t val; \
911 		pcwl_swap_len--; \
912 		val = *((uint16_t *)(buf_p) + pcwl_swap_len); \
913 		*((uint16_t *)(buf_p) + pcwl_swap_len) = LE_16(val); \
914 	} \
915 }
916 #else /* _BIG_ENDIAN */
917 #define	PCWL_SWAP16(buf_p, len)
918 #endif /* _BIG_ENDIAN */
919 
920 #define	PCWL_ENABLE_INTR(pcwl_p)	{\
921 	PCWL_WRITE(pcwl_p, WL_INT_EN, WL_INTRS);\
922 }
923 #define	PCWL_DISABLE_INTR(pcwl_p)	{ \
924 	PCWL_WRITE(pcwl_p, WL_INT_EN, 0); \
925 	PCWL_WRITE(pcwl_p, WL_EVENT_ACK, 0xffff);\
926 }
927 
928 /*
929  * 16-bit driver private status code
930  */
931 #define	PCWL_SUCCESS		0x0
932 #define	PCWL_FAIL		0x1
933 #define	PCWL_TIMEDOUT_CMD	0x10
934 #define	PCWL_TIMEDOUT_ACCESS	0x11
935 #define	PCWL_TIMEDOUT_TARGET	0x12
936 #define	PCWL_BADLEN		0x13
937 #define	PCWL_BADTYPE		0x14
938 #define	PCWL_TIMEDOUT_ALLOC	0x15
939 #define	PCWL_FAILURE_CMD	0x16
940 
941 #define	PCWL_STATUS_MAX		0xffff
942 #define	N_PCWL			2
943 
944 #ifdef	__cplusplus
945 }
946 #endif
947 
948 #endif	/* _SYS_PCWL_H */
949