xref: /illumos-gate/usr/src/uts/common/io/wpi/wpi.c (revision 86c48bbfeb72d5a6ee171e713059939bab658b77)
1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2006
8  *	Damien Bergamini <damien.bergamini@free.fr>
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 /*
24  * Driver for Intel PRO/Wireless 3945ABG 802.11 network adapters.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/byteorder.h>
29 #include <sys/conf.h>
30 #include <sys/cmn_err.h>
31 #include <sys/stat.h>
32 #include <sys/ddi.h>
33 #include <sys/sunddi.h>
34 #include <sys/strsubr.h>
35 #include <sys/ethernet.h>
36 #include <inet/common.h>
37 #include <inet/nd.h>
38 #include <inet/mi.h>
39 #include <sys/note.h>
40 #include <sys/stream.h>
41 #include <sys/strsun.h>
42 #include <sys/modctl.h>
43 #include <sys/devops.h>
44 #include <sys/dlpi.h>
45 #include <sys/mac_provider.h>
46 #include <sys/mac_wifi.h>
47 #include <sys/net80211.h>
48 #include <sys/net80211_proto.h>
49 #include <sys/varargs.h>
50 #include <sys/policy.h>
51 #include <sys/pci.h>
52 
53 #include "wpireg.h"
54 #include "wpivar.h"
55 #include <inet/wifi_ioctl.h>
56 
57 #ifdef DEBUG
58 #define	WPI_DEBUG_80211		(1 << 0)
59 #define	WPI_DEBUG_CMD		(1 << 1)
60 #define	WPI_DEBUG_DMA		(1 << 2)
61 #define	WPI_DEBUG_EEPROM	(1 << 3)
62 #define	WPI_DEBUG_FW		(1 << 4)
63 #define	WPI_DEBUG_HW		(1 << 5)
64 #define	WPI_DEBUG_INTR		(1 << 6)
65 #define	WPI_DEBUG_MRR		(1 << 7)
66 #define	WPI_DEBUG_PIO		(1 << 8)
67 #define	WPI_DEBUG_RX		(1 << 9)
68 #define	WPI_DEBUG_SCAN		(1 << 10)
69 #define	WPI_DEBUG_TX		(1 << 11)
70 #define	WPI_DEBUG_RATECTL	(1 << 12)
71 #define	WPI_DEBUG_RADIO		(1 << 13)
72 #define	WPI_DEBUG_RESUME	(1 << 14)
73 uint32_t wpi_dbg_flags = 0;
74 #define	WPI_DBG(x) \
75 	wpi_dbg x
76 #else
77 #define	WPI_DBG(x)
78 #endif
79 
80 static void	*wpi_soft_state_p = NULL;
81 static uint8_t wpi_fw_bin [] = {
82 #include "fw-wpi/ipw3945.ucode.hex"
83 };
84 
85 /* DMA attributes for a shared page */
86 static ddi_dma_attr_t sh_dma_attr = {
87 	DMA_ATTR_V0,	/* version of this structure */
88 	0,		/* lowest usable address */
89 	0xffffffffU,	/* highest usable address */
90 	0xffffffffU,	/* maximum DMAable byte count */
91 	0x1000,		/* alignment in bytes */
92 	0x1000,		/* burst sizes (any?) */
93 	1,		/* minimum transfer */
94 	0xffffffffU,	/* maximum transfer */
95 	0xffffffffU,	/* maximum segment length */
96 	1,		/* maximum number of segments */
97 	1,		/* granularity */
98 	0,		/* flags (reserved) */
99 };
100 
101 /* DMA attributes for a ring descriptor */
102 static ddi_dma_attr_t ring_desc_dma_attr = {
103 	DMA_ATTR_V0,	/* version of this structure */
104 	0,		/* lowest usable address */
105 	0xffffffffU,	/* highest usable address */
106 	0xffffffffU,	/* maximum DMAable byte count */
107 	0x4000,		/* alignment in bytes */
108 	0x100,		/* burst sizes (any?) */
109 	1,		/* minimum transfer */
110 	0xffffffffU,	/* maximum transfer */
111 	0xffffffffU,	/* maximum segment length */
112 	1,		/* maximum number of segments */
113 	1,		/* granularity */
114 	0,		/* flags (reserved) */
115 };
116 
117 
118 /* DMA attributes for a tx cmd */
119 static ddi_dma_attr_t tx_cmd_dma_attr = {
120 	DMA_ATTR_V0,	/* version of this structure */
121 	0,		/* lowest usable address */
122 	0xffffffffU,	/* highest usable address */
123 	0xffffffffU,	/* maximum DMAable byte count */
124 	4,		/* alignment in bytes */
125 	0x100,		/* burst sizes (any?) */
126 	1,		/* minimum transfer */
127 	0xffffffffU,	/* maximum transfer */
128 	0xffffffffU,	/* maximum segment length */
129 	1,		/* maximum number of segments */
130 	1,		/* granularity */
131 	0,		/* flags (reserved) */
132 };
133 
134 /* DMA attributes for a rx buffer */
135 static ddi_dma_attr_t rx_buffer_dma_attr = {
136 	DMA_ATTR_V0,	/* version of this structure */
137 	0,		/* lowest usable address */
138 	0xffffffffU,	/* highest usable address */
139 	0xffffffffU,	/* maximum DMAable byte count */
140 	1,		/* alignment in bytes */
141 	0x100,		/* burst sizes (any?) */
142 	1,		/* minimum transfer */
143 	0xffffffffU,	/* maximum transfer */
144 	0xffffffffU,	/* maximum segment length */
145 	1,		/* maximum number of segments */
146 	1,		/* granularity */
147 	0,		/* flags (reserved) */
148 };
149 
150 /*
151  * DMA attributes for a tx buffer.
152  * the maximum number of segments is 4 for the hardware.
153  * now all the wifi drivers put the whole frame in a single
154  * descriptor, so we define the maximum  number of segments 4,
155  * just the same as the rx_buffer. we consider leverage the HW
156  * ability in the future, that is why we don't define rx and tx
157  * buffer_dma_attr as the same.
158  */
159 static ddi_dma_attr_t tx_buffer_dma_attr = {
160 	DMA_ATTR_V0,	/* version of this structure */
161 	0,		/* lowest usable address */
162 	0xffffffffU,	/* highest usable address */
163 	0xffffffffU,	/* maximum DMAable byte count */
164 	1,		/* alignment in bytes */
165 	0x100,		/* burst sizes (any?) */
166 	1,		/* minimum transfer */
167 	0xffffffffU,	/* maximum transfer */
168 	0xffffffffU,	/* maximum segment length */
169 	1,		/* maximum number of segments */
170 	1,		/* granularity */
171 	0,		/* flags (reserved) */
172 };
173 
174 /* DMA attributes for a load firmware */
175 static ddi_dma_attr_t fw_buffer_dma_attr = {
176 	DMA_ATTR_V0,	/* version of this structure */
177 	0,		/* lowest usable address */
178 	0xffffffffU,	/* highest usable address */
179 	0x7fffffff,	/* maximum DMAable byte count */
180 	4,		/* alignment in bytes */
181 	0x100,		/* burst sizes (any?) */
182 	1,		/* minimum transfer */
183 	0xffffffffU,	/* maximum transfer */
184 	0xffffffffU,	/* maximum segment length */
185 	4,		/* maximum number of segments */
186 	1,		/* granularity */
187 	0,		/* flags (reserved) */
188 };
189 
190 /* regs access attributes */
191 static ddi_device_acc_attr_t wpi_reg_accattr = {
192 	DDI_DEVICE_ATTR_V0,
193 	DDI_STRUCTURE_LE_ACC,
194 	DDI_STRICTORDER_ACC,
195 	DDI_DEFAULT_ACC
196 };
197 
198 /* DMA access attributes */
199 static ddi_device_acc_attr_t wpi_dma_accattr = {
200 	DDI_DEVICE_ATTR_V0,
201 	DDI_NEVERSWAP_ACC,
202 	DDI_STRICTORDER_ACC,
203 	DDI_DEFAULT_ACC
204 };
205 
206 static int	wpi_ring_init(wpi_sc_t *);
207 static void	wpi_ring_free(wpi_sc_t *);
208 static int	wpi_alloc_shared(wpi_sc_t *);
209 static void	wpi_free_shared(wpi_sc_t *);
210 static int	wpi_alloc_fw_dma(wpi_sc_t *);
211 static void	wpi_free_fw_dma(wpi_sc_t *);
212 static int	wpi_alloc_rx_ring(wpi_sc_t *);
213 static void	wpi_reset_rx_ring(wpi_sc_t *);
214 static void	wpi_free_rx_ring(wpi_sc_t *);
215 static int	wpi_alloc_tx_ring(wpi_sc_t *, wpi_tx_ring_t *, int, int);
216 static void	wpi_reset_tx_ring(wpi_sc_t *, wpi_tx_ring_t *);
217 static void	wpi_free_tx_ring(wpi_sc_t *, wpi_tx_ring_t *);
218 
219 static ieee80211_node_t *wpi_node_alloc(ieee80211com_t *);
220 static void	wpi_node_free(ieee80211_node_t *);
221 static int	wpi_newstate(ieee80211com_t *, enum ieee80211_state, int);
222 static int	wpi_key_set(ieee80211com_t *, const struct ieee80211_key *,
223     const uint8_t mac[IEEE80211_ADDR_LEN]);
224 static void	wpi_mem_lock(wpi_sc_t *);
225 static void	wpi_mem_unlock(wpi_sc_t *);
226 static uint32_t	wpi_mem_read(wpi_sc_t *, uint16_t);
227 static void	wpi_mem_write(wpi_sc_t *, uint16_t, uint32_t);
228 static void	wpi_mem_write_region_4(wpi_sc_t *, uint16_t,
229 		    const uint32_t *, int);
230 static uint16_t	wpi_read_prom_word(wpi_sc_t *, uint32_t);
231 static int	wpi_load_microcode(wpi_sc_t *);
232 static int	wpi_load_firmware(wpi_sc_t *, uint32_t);
233 static void	wpi_rx_intr(wpi_sc_t *, wpi_rx_desc_t *,
234 		    wpi_rx_data_t *);
235 static void	wpi_tx_intr(wpi_sc_t *, wpi_rx_desc_t *,
236 		    wpi_rx_data_t *);
237 static void	wpi_cmd_intr(wpi_sc_t *, wpi_rx_desc_t *);
238 static uint_t	wpi_intr(caddr_t);
239 static uint_t	wpi_notif_softintr(caddr_t);
240 static uint8_t	wpi_plcp_signal(int);
241 static void	wpi_read_eeprom(wpi_sc_t *);
242 static int	wpi_cmd(wpi_sc_t *, int, const void *, int, int);
243 static int	wpi_mrr_setup(wpi_sc_t *);
244 static void	wpi_set_led(wpi_sc_t *, uint8_t, uint8_t, uint8_t);
245 static int	wpi_auth(wpi_sc_t *);
246 static int	wpi_scan(wpi_sc_t *);
247 static int	wpi_config(wpi_sc_t *);
248 static void	wpi_stop_master(wpi_sc_t *);
249 static int	wpi_power_up(wpi_sc_t *);
250 static int	wpi_reset(wpi_sc_t *);
251 static void	wpi_hw_config(wpi_sc_t *);
252 static int	wpi_init(wpi_sc_t *);
253 static void	wpi_stop(wpi_sc_t *);
254 static int	wpi_quiesce(dev_info_t *dip);
255 static void	wpi_amrr_init(wpi_amrr_t *);
256 static void	wpi_amrr_timeout(wpi_sc_t *);
257 static void	wpi_amrr_ratectl(void *, ieee80211_node_t *);
258 
259 static int wpi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
260 static int wpi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
261 
262 /*
263  * GLD specific operations
264  */
265 static int	wpi_m_stat(void *arg, uint_t stat, uint64_t *val);
266 static int	wpi_m_start(void *arg);
267 static void	wpi_m_stop(void *arg);
268 static int	wpi_m_unicst(void *arg, const uint8_t *macaddr);
269 static int	wpi_m_multicst(void *arg, boolean_t add, const uint8_t *m);
270 static int	wpi_m_promisc(void *arg, boolean_t on);
271 static mblk_t  *wpi_m_tx(void *arg, mblk_t *mp);
272 static void	wpi_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
273 static int	wpi_m_setprop(void *arg, const char *pr_name,
274     mac_prop_id_t wldp_pr_num, uint_t wldp_length, const void *wldp_buf);
275 static int	wpi_m_getprop(void *arg, const char *pr_name,
276     mac_prop_id_t wldp_pr_num, uint_t pr_flags, uint_t wldp_lenth,
277     void *wldp_buf, uint_t *);
278 static void	wpi_destroy_locks(wpi_sc_t *sc);
279 static int	wpi_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type);
280 static void	wpi_thread(wpi_sc_t *sc);
281 
282 /*
283  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
284  */
285 static const struct ieee80211_rateset wpi_rateset_11b =
286 	{ 4, { 2, 4, 11, 22 } };
287 
288 static const struct ieee80211_rateset wpi_rateset_11g =
289 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
290 
291 static const uint8_t wpi_ridx_to_signal[] = {
292 	/* OFDM: IEEE Std 802.11a-1999, pp. 14 Table 80 */
293 	/* R1-R4 (ral/ural is R4-R1) */
294 	0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3,
295 	/* CCK: device-dependent */
296 	10, 20, 55, 110
297 };
298 
299 /*
300  * For mfthread only
301  */
302 extern pri_t minclsyspri;
303 
304 /*
305  * Module Loading Data & Entry Points
306  */
307 DDI_DEFINE_STREAM_OPS(wpi_devops, nulldev, nulldev, wpi_attach,
308     wpi_detach, nodev, NULL, D_MP, NULL, wpi_quiesce);
309 
310 static struct modldrv wpi_modldrv = {
311 	&mod_driverops,
312 	"Intel(R) PRO/Wireless 3945ABG driver",
313 	&wpi_devops
314 };
315 
316 static struct modlinkage wpi_modlinkage = {
317 	MODREV_1,
318 	&wpi_modldrv,
319 	NULL
320 };
321 
322 int
323 _init(void)
324 {
325 	int	status;
326 
327 	status = ddi_soft_state_init(&wpi_soft_state_p,
328 	    sizeof (wpi_sc_t), 1);
329 	if (status != DDI_SUCCESS)
330 		return (status);
331 
332 	mac_init_ops(&wpi_devops, "wpi");
333 	status = mod_install(&wpi_modlinkage);
334 	if (status != DDI_SUCCESS) {
335 		mac_fini_ops(&wpi_devops);
336 		ddi_soft_state_fini(&wpi_soft_state_p);
337 	}
338 
339 	return (status);
340 }
341 
342 int
343 _fini(void)
344 {
345 	int status;
346 
347 	status = mod_remove(&wpi_modlinkage);
348 	if (status == DDI_SUCCESS) {
349 		mac_fini_ops(&wpi_devops);
350 		ddi_soft_state_fini(&wpi_soft_state_p);
351 	}
352 
353 	return (status);
354 }
355 
356 int
357 _info(struct modinfo *mip)
358 {
359 	return (mod_info(&wpi_modlinkage, mip));
360 }
361 
362 /*
363  * Mac Call Back entries
364  */
365 mac_callbacks_t	wpi_m_callbacks = {
366 	MC_IOCTL | MC_SETPROP | MC_GETPROP,
367 	wpi_m_stat,
368 	wpi_m_start,
369 	wpi_m_stop,
370 	wpi_m_promisc,
371 	wpi_m_multicst,
372 	wpi_m_unicst,
373 	wpi_m_tx,
374 	wpi_m_ioctl,
375 	NULL,
376 	NULL,
377 	NULL,
378 	wpi_m_setprop,
379 	wpi_m_getprop
380 };
381 
382 #ifdef DEBUG
383 void
384 wpi_dbg(uint32_t flags, const char *fmt, ...)
385 {
386 	va_list	ap;
387 
388 	if (flags & wpi_dbg_flags) {
389 		va_start(ap, fmt);
390 		vcmn_err(CE_NOTE, fmt, ap);
391 		va_end(ap);
392 	}
393 }
394 #endif
395 /*
396  * device operations
397  */
398 int
399 wpi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
400 {
401 	wpi_sc_t		*sc;
402 	ddi_acc_handle_t	cfg_handle;
403 	caddr_t			cfg_base;
404 	ieee80211com_t	*ic;
405 	int			instance, err, i;
406 	char			strbuf[32];
407 	wifi_data_t		wd = { 0 };
408 	mac_register_t		*macp;
409 
410 	switch (cmd) {
411 	case DDI_ATTACH:
412 		break;
413 	case DDI_RESUME:
414 		sc = ddi_get_soft_state(wpi_soft_state_p,
415 		    ddi_get_instance(dip));
416 		ASSERT(sc != NULL);
417 
418 		mutex_enter(&sc->sc_glock);
419 		sc->sc_flags &= ~WPI_F_SUSPEND;
420 		mutex_exit(&sc->sc_glock);
421 
422 		if (sc->sc_flags & WPI_F_RUNNING)
423 			(void) wpi_init(sc);
424 
425 		mutex_enter(&sc->sc_glock);
426 		sc->sc_flags |= WPI_F_LAZY_RESUME;
427 		mutex_exit(&sc->sc_glock);
428 
429 		WPI_DBG((WPI_DEBUG_RESUME, "wpi: resume \n"));
430 		return (DDI_SUCCESS);
431 	default:
432 		err = DDI_FAILURE;
433 		goto attach_fail1;
434 	}
435 
436 	instance = ddi_get_instance(dip);
437 	err = ddi_soft_state_zalloc(wpi_soft_state_p, instance);
438 	if (err != DDI_SUCCESS) {
439 		cmn_err(CE_WARN,
440 		    "wpi_attach(): failed to allocate soft state\n");
441 		goto attach_fail1;
442 	}
443 	sc = ddi_get_soft_state(wpi_soft_state_p, instance);
444 	sc->sc_dip = dip;
445 
446 	err = ddi_regs_map_setup(dip, 0, &cfg_base, 0, 0,
447 	    &wpi_reg_accattr, &cfg_handle);
448 	if (err != DDI_SUCCESS) {
449 		cmn_err(CE_WARN,
450 		    "wpi_attach(): failed to map config spaces regs\n");
451 		goto attach_fail2;
452 	}
453 	sc->sc_rev = ddi_get8(cfg_handle,
454 	    (uint8_t *)(cfg_base + PCI_CONF_REVID));
455 	ddi_put8(cfg_handle, (uint8_t *)(cfg_base + 0x41), 0);
456 	sc->sc_clsz = ddi_get16(cfg_handle,
457 	    (uint16_t *)(cfg_base + PCI_CONF_CACHE_LINESZ));
458 	ddi_regs_map_free(&cfg_handle);
459 	if (!sc->sc_clsz)
460 		sc->sc_clsz = 16;
461 	sc->sc_clsz = (sc->sc_clsz << 2);
462 	sc->sc_dmabuf_sz = roundup(0x1000 + sizeof (struct ieee80211_frame) +
463 	    IEEE80211_MTU + IEEE80211_CRC_LEN +
464 	    (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
465 	    IEEE80211_WEP_CRCLEN), sc->sc_clsz);
466 	/*
467 	 * Map operating registers
468 	 */
469 	err = ddi_regs_map_setup(dip, 1, &sc->sc_base,
470 	    0, 0, &wpi_reg_accattr, &sc->sc_handle);
471 	if (err != DDI_SUCCESS) {
472 		cmn_err(CE_WARN,
473 		    "wpi_attach(): failed to map device regs\n");
474 		goto attach_fail2;
475 	}
476 
477 	/*
478 	 * Allocate shared page.
479 	 */
480 	err = wpi_alloc_shared(sc);
481 	if (err != DDI_SUCCESS) {
482 		cmn_err(CE_WARN, "failed to allocate shared page\n");
483 		goto attach_fail3;
484 	}
485 
486 	/*
487 	 * Get the hw conf, including MAC address, then init all rings.
488 	 */
489 	wpi_read_eeprom(sc);
490 	err = wpi_ring_init(sc);
491 	if (err != DDI_SUCCESS) {
492 		cmn_err(CE_WARN, "wpi_attach(): "
493 		    "failed to allocate and initialize ring\n");
494 		goto attach_fail4;
495 	}
496 
497 	sc->sc_hdr = (const wpi_firmware_hdr_t *)wpi_fw_bin;
498 
499 	/* firmware image layout: |HDR|<--TEXT-->|<--DATA-->|<--BOOT-->| */
500 	sc->sc_text = (const char *)(sc->sc_hdr + 1);
501 	sc->sc_data = sc->sc_text + LE_32(sc->sc_hdr->textsz);
502 	sc->sc_boot = sc->sc_data + LE_32(sc->sc_hdr->datasz);
503 	err = wpi_alloc_fw_dma(sc);
504 	if (err != DDI_SUCCESS) {
505 		cmn_err(CE_WARN, "wpi_attach(): "
506 		    "failed to allocate firmware dma\n");
507 		goto attach_fail5;
508 	}
509 
510 	/*
511 	 * Initialize mutexs and condvars
512 	 */
513 	err = ddi_get_iblock_cookie(dip, 0, &sc->sc_iblk);
514 	if (err != DDI_SUCCESS) {
515 		cmn_err(CE_WARN,
516 		    "wpi_attach(): failed to do ddi_get_iblock_cookie()\n");
517 		goto attach_fail6;
518 	}
519 	mutex_init(&sc->sc_glock, NULL, MUTEX_DRIVER, sc->sc_iblk);
520 	mutex_init(&sc->sc_tx_lock, NULL, MUTEX_DRIVER, sc->sc_iblk);
521 	cv_init(&sc->sc_fw_cv, NULL, CV_DRIVER, NULL);
522 	cv_init(&sc->sc_cmd_cv, NULL, CV_DRIVER, NULL);
523 
524 	/*
525 	 * initialize the mfthread
526 	 */
527 	mutex_init(&sc->sc_mt_lock, NULL, MUTEX_DRIVER,
528 	    (void *) sc->sc_iblk);
529 	cv_init(&sc->sc_mt_cv, NULL, CV_DRIVER, NULL);
530 	sc->sc_mf_thread = NULL;
531 	sc->sc_mf_thread_switch = 0;
532 	/*
533 	 * Initialize the wifi part, which will be used by
534 	 * generic layer
535 	 */
536 	ic = &sc->sc_ic;
537 	ic->ic_phytype  = IEEE80211_T_OFDM;
538 	ic->ic_opmode   = IEEE80211_M_STA; /* default to BSS mode */
539 	ic->ic_state    = IEEE80211_S_INIT;
540 	ic->ic_maxrssi  = 70; /* experimental number */
541 	ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT |
542 	    IEEE80211_C_PMGT | IEEE80211_C_SHSLOT;
543 
544 	/*
545 	 * use software WEP and TKIP, hardware CCMP;
546 	 */
547 	ic->ic_caps |= IEEE80211_C_AES_CCM;
548 	ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */
549 
550 	/* set supported .11b and .11g rates */
551 	ic->ic_sup_rates[IEEE80211_MODE_11B] = wpi_rateset_11b;
552 	ic->ic_sup_rates[IEEE80211_MODE_11G] = wpi_rateset_11g;
553 
554 	/* set supported .11b and .11g channels (1 through 14) */
555 	for (i = 1; i <= 14; i++) {
556 		ic->ic_sup_channels[i].ich_freq =
557 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
558 		ic->ic_sup_channels[i].ich_flags =
559 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
560 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ |
561 		    IEEE80211_CHAN_PASSIVE;
562 	}
563 	ic->ic_ibss_chan = &ic->ic_sup_channels[0];
564 	ic->ic_xmit = wpi_send;
565 	/*
566 	 * init Wifi layer
567 	 */
568 	ieee80211_attach(ic);
569 
570 	/* register WPA door */
571 	ieee80211_register_door(ic, ddi_driver_name(dip),
572 	    ddi_get_instance(dip));
573 
574 	/*
575 	 * Override 80211 default routines
576 	 */
577 	sc->sc_newstate = ic->ic_newstate;
578 	ic->ic_newstate = wpi_newstate;
579 	ic->ic_node_alloc = wpi_node_alloc;
580 	ic->ic_node_free = wpi_node_free;
581 	ic->ic_crypto.cs_key_set = wpi_key_set;
582 	ieee80211_media_init(ic);
583 	/*
584 	 * initialize default tx key
585 	 */
586 	ic->ic_def_txkey = 0;
587 
588 	err = ddi_add_softintr(dip, DDI_SOFTINT_LOW,
589 	    &sc->sc_notif_softint_id, &sc->sc_iblk, NULL, wpi_notif_softintr,
590 	    (caddr_t)sc);
591 	if (err != DDI_SUCCESS) {
592 		cmn_err(CE_WARN,
593 		    "wpi_attach(): failed to do ddi_add_softintr()\n");
594 		goto attach_fail7;
595 	}
596 
597 	/*
598 	 * Add the interrupt handler
599 	 */
600 	err = ddi_add_intr(dip, 0, &sc->sc_iblk, NULL,
601 	    wpi_intr, (caddr_t)sc);
602 	if (err != DDI_SUCCESS) {
603 		cmn_err(CE_WARN,
604 		    "wpi_attach(): failed to do ddi_add_intr()\n");
605 		goto attach_fail8;
606 	}
607 
608 	/*
609 	 * Initialize pointer to device specific functions
610 	 */
611 	wd.wd_secalloc = WIFI_SEC_NONE;
612 	wd.wd_opmode = ic->ic_opmode;
613 	IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_macaddr);
614 
615 	macp = mac_alloc(MAC_VERSION);
616 	if (err != DDI_SUCCESS) {
617 		cmn_err(CE_WARN,
618 		    "wpi_attach(): failed to do mac_alloc()\n");
619 		goto attach_fail9;
620 	}
621 
622 	macp->m_type_ident	= MAC_PLUGIN_IDENT_WIFI;
623 	macp->m_driver		= sc;
624 	macp->m_dip		= dip;
625 	macp->m_src_addr	= ic->ic_macaddr;
626 	macp->m_callbacks	= &wpi_m_callbacks;
627 	macp->m_min_sdu		= 0;
628 	macp->m_max_sdu		= IEEE80211_MTU;
629 	macp->m_pdata		= &wd;
630 	macp->m_pdata_size	= sizeof (wd);
631 
632 	/*
633 	 * Register the macp to mac
634 	 */
635 	err = mac_register(macp, &ic->ic_mach);
636 	mac_free(macp);
637 	if (err != DDI_SUCCESS) {
638 		cmn_err(CE_WARN,
639 		    "wpi_attach(): failed to do mac_register()\n");
640 		goto attach_fail9;
641 	}
642 
643 	/*
644 	 * Create minor node of type DDI_NT_NET_WIFI
645 	 */
646 	(void) snprintf(strbuf, sizeof (strbuf), "wpi%d", instance);
647 	err = ddi_create_minor_node(dip, strbuf, S_IFCHR,
648 	    instance + 1, DDI_NT_NET_WIFI, 0);
649 	if (err != DDI_SUCCESS)
650 		cmn_err(CE_WARN,
651 		    "wpi_attach(): failed to do ddi_create_minor_node()\n");
652 
653 	/*
654 	 * Notify link is down now
655 	 */
656 	mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
657 
658 	/*
659 	 * create the mf thread to handle the link status,
660 	 * recovery fatal error, etc.
661 	 */
662 
663 	sc->sc_mf_thread_switch = 1;
664 	if (sc->sc_mf_thread == NULL)
665 		sc->sc_mf_thread = thread_create((caddr_t)NULL, 0,
666 		    wpi_thread, sc, 0, &p0, TS_RUN, minclsyspri);
667 
668 	sc->sc_flags |= WPI_F_ATTACHED;
669 
670 	return (DDI_SUCCESS);
671 attach_fail9:
672 	ddi_remove_intr(dip, 0, sc->sc_iblk);
673 attach_fail8:
674 	ddi_remove_softintr(sc->sc_notif_softint_id);
675 	sc->sc_notif_softint_id = NULL;
676 attach_fail7:
677 	ieee80211_detach(ic);
678 	wpi_destroy_locks(sc);
679 attach_fail6:
680 	wpi_free_fw_dma(sc);
681 attach_fail5:
682 	wpi_ring_free(sc);
683 attach_fail4:
684 	wpi_free_shared(sc);
685 attach_fail3:
686 	ddi_regs_map_free(&sc->sc_handle);
687 attach_fail2:
688 	ddi_soft_state_free(wpi_soft_state_p, instance);
689 attach_fail1:
690 	return (err);
691 }
692 
693 int
694 wpi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
695 {
696 	wpi_sc_t	*sc;
697 	int err;
698 
699 	sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip));
700 	ASSERT(sc != NULL);
701 
702 	switch (cmd) {
703 	case DDI_DETACH:
704 		break;
705 	case DDI_SUSPEND:
706 		mutex_enter(&sc->sc_glock);
707 		sc->sc_flags |= WPI_F_SUSPEND;
708 		mutex_exit(&sc->sc_glock);
709 
710 		if (sc->sc_flags & WPI_F_RUNNING) {
711 			wpi_stop(sc);
712 		}
713 
714 		WPI_DBG((WPI_DEBUG_RESUME, "wpi: suspend \n"));
715 		return (DDI_SUCCESS);
716 	default:
717 		return (DDI_FAILURE);
718 	}
719 	if (!(sc->sc_flags & WPI_F_ATTACHED))
720 		return (DDI_FAILURE);
721 
722 	err = mac_disable(sc->sc_ic.ic_mach);
723 	if (err != DDI_SUCCESS)
724 		return (err);
725 
726 	/*
727 	 * Destroy the mf_thread
728 	 */
729 	mutex_enter(&sc->sc_mt_lock);
730 	sc->sc_mf_thread_switch = 0;
731 	while (sc->sc_mf_thread != NULL) {
732 		if (cv_wait_sig(&sc->sc_mt_cv, &sc->sc_mt_lock) == 0)
733 			break;
734 	}
735 	mutex_exit(&sc->sc_mt_lock);
736 
737 	wpi_stop(sc);
738 
739 	/*
740 	 * Unregiste from the MAC layer subsystem
741 	 */
742 	(void) mac_unregister(sc->sc_ic.ic_mach);
743 
744 	mutex_enter(&sc->sc_glock);
745 	wpi_free_fw_dma(sc);
746 	wpi_ring_free(sc);
747 	wpi_free_shared(sc);
748 	mutex_exit(&sc->sc_glock);
749 
750 	ddi_remove_intr(dip, 0, sc->sc_iblk);
751 	ddi_remove_softintr(sc->sc_notif_softint_id);
752 	sc->sc_notif_softint_id = NULL;
753 
754 	/*
755 	 * detach ieee80211
756 	 */
757 	ieee80211_detach(&sc->sc_ic);
758 
759 	wpi_destroy_locks(sc);
760 
761 	ddi_regs_map_free(&sc->sc_handle);
762 	ddi_remove_minor_node(dip, NULL);
763 	ddi_soft_state_free(wpi_soft_state_p, ddi_get_instance(dip));
764 
765 	return (DDI_SUCCESS);
766 }
767 
768 static void
769 wpi_destroy_locks(wpi_sc_t *sc)
770 {
771 	cv_destroy(&sc->sc_mt_cv);
772 	mutex_destroy(&sc->sc_mt_lock);
773 	cv_destroy(&sc->sc_cmd_cv);
774 	cv_destroy(&sc->sc_fw_cv);
775 	mutex_destroy(&sc->sc_tx_lock);
776 	mutex_destroy(&sc->sc_glock);
777 }
778 
779 /*
780  * Allocate an area of memory and a DMA handle for accessing it
781  */
782 static int
783 wpi_alloc_dma_mem(wpi_sc_t *sc, size_t memsize, ddi_dma_attr_t *dma_attr_p,
784 	ddi_device_acc_attr_t *acc_attr_p, uint_t dma_flags, wpi_dma_t *dma_p)
785 {
786 	caddr_t vaddr;
787 	int err;
788 
789 	/*
790 	 * Allocate handle
791 	 */
792 	err = ddi_dma_alloc_handle(sc->sc_dip, dma_attr_p,
793 	    DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
794 	if (err != DDI_SUCCESS) {
795 		dma_p->dma_hdl = NULL;
796 		return (DDI_FAILURE);
797 	}
798 
799 	/*
800 	 * Allocate memory
801 	 */
802 	err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, acc_attr_p,
803 	    dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING),
804 	    DDI_DMA_SLEEP, NULL, &vaddr, &dma_p->alength, &dma_p->acc_hdl);
805 	if (err != DDI_SUCCESS) {
806 		ddi_dma_free_handle(&dma_p->dma_hdl);
807 		dma_p->dma_hdl = NULL;
808 		dma_p->acc_hdl = NULL;
809 		return (DDI_FAILURE);
810 	}
811 
812 	/*
813 	 * Bind the two together
814 	 */
815 	dma_p->mem_va = vaddr;
816 	err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
817 	    vaddr, dma_p->alength, dma_flags, DDI_DMA_SLEEP, NULL,
818 	    &dma_p->cookie, &dma_p->ncookies);
819 	if (err != DDI_DMA_MAPPED) {
820 		ddi_dma_mem_free(&dma_p->acc_hdl);
821 		ddi_dma_free_handle(&dma_p->dma_hdl);
822 		dma_p->acc_hdl = NULL;
823 		dma_p->dma_hdl = NULL;
824 		return (DDI_FAILURE);
825 	}
826 
827 	dma_p->nslots = ~0U;
828 	dma_p->size = ~0U;
829 	dma_p->token = ~0U;
830 	dma_p->offset = 0;
831 	return (DDI_SUCCESS);
832 }
833 
834 /*
835  * Free one allocated area of DMAable memory
836  */
837 static void
838 wpi_free_dma_mem(wpi_dma_t *dma_p)
839 {
840 	if (dma_p->dma_hdl != NULL) {
841 		if (dma_p->ncookies) {
842 			(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
843 			dma_p->ncookies = 0;
844 		}
845 		ddi_dma_free_handle(&dma_p->dma_hdl);
846 		dma_p->dma_hdl = NULL;
847 	}
848 
849 	if (dma_p->acc_hdl != NULL) {
850 		ddi_dma_mem_free(&dma_p->acc_hdl);
851 		dma_p->acc_hdl = NULL;
852 	}
853 }
854 
855 /*
856  * Allocate an area of dma memory for firmware load.
857  * Idealy, this allocation should be a one time action, that is,
858  * the memory will be freed after the firmware is uploaded to the
859  * card. but since a recovery mechanism for the fatal firmware need
860  * reload the firmware, and re-allocate dma at run time may be failed,
861  * so we allocate it at attach and keep it in the whole lifecycle of
862  * the driver.
863  */
864 static int
865 wpi_alloc_fw_dma(wpi_sc_t *sc)
866 {
867 	int i, err = DDI_SUCCESS;
868 	wpi_dma_t *dma_p;
869 
870 	err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->textsz),
871 	    &fw_buffer_dma_attr, &wpi_dma_accattr,
872 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
873 	    &sc->sc_dma_fw_text);
874 	dma_p = &sc->sc_dma_fw_text;
875 	WPI_DBG((WPI_DEBUG_DMA, "ncookies:%d addr1:%x size1:%x\n",
876 	    dma_p->ncookies, dma_p->cookie.dmac_address,
877 	    dma_p->cookie.dmac_size));
878 	if (err != DDI_SUCCESS) {
879 		cmn_err(CE_WARN, "wpi_alloc_fw_dma(): failed to alloc"
880 		    "text dma memory");
881 		goto fail;
882 	}
883 	for (i = 0; i < dma_p->ncookies; i++) {
884 		sc->sc_fw_text_cookie[i] = dma_p->cookie;
885 		ddi_dma_nextcookie(dma_p->dma_hdl, &dma_p->cookie);
886 	}
887 	err = wpi_alloc_dma_mem(sc, LE_32(sc->sc_hdr->datasz),
888 	    &fw_buffer_dma_attr, &wpi_dma_accattr,
889 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
890 	    &sc->sc_dma_fw_data);
891 	dma_p = &sc->sc_dma_fw_data;
892 	WPI_DBG((WPI_DEBUG_DMA, "ncookies:%d addr1:%x size1:%x\n",
893 	    dma_p->ncookies, dma_p->cookie.dmac_address,
894 	    dma_p->cookie.dmac_size));
895 	if (err != DDI_SUCCESS) {
896 		cmn_err(CE_WARN, "wpi_alloc_fw_dma(): failed to alloc"
897 		    "data dma memory");
898 		goto fail;
899 	}
900 	for (i = 0; i < dma_p->ncookies; i++) {
901 		sc->sc_fw_data_cookie[i] = dma_p->cookie;
902 		ddi_dma_nextcookie(dma_p->dma_hdl, &dma_p->cookie);
903 	}
904 fail:
905 	return (err);
906 }
907 
908 static void
909 wpi_free_fw_dma(wpi_sc_t *sc)
910 {
911 	wpi_free_dma_mem(&sc->sc_dma_fw_text);
912 	wpi_free_dma_mem(&sc->sc_dma_fw_data);
913 }
914 
915 /*
916  * Allocate a shared page between host and NIC.
917  */
918 static int
919 wpi_alloc_shared(wpi_sc_t *sc)
920 {
921 	int err = DDI_SUCCESS;
922 
923 	/* must be aligned on a 4K-page boundary */
924 	err = wpi_alloc_dma_mem(sc, sizeof (wpi_shared_t),
925 	    &sh_dma_attr, &wpi_dma_accattr,
926 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
927 	    &sc->sc_dma_sh);
928 	if (err != DDI_SUCCESS)
929 		goto fail;
930 	sc->sc_shared = (wpi_shared_t *)sc->sc_dma_sh.mem_va;
931 	return (err);
932 
933 fail:
934 	wpi_free_shared(sc);
935 	return (err);
936 }
937 
938 static void
939 wpi_free_shared(wpi_sc_t *sc)
940 {
941 	wpi_free_dma_mem(&sc->sc_dma_sh);
942 }
943 
944 static int
945 wpi_alloc_rx_ring(wpi_sc_t *sc)
946 {
947 	wpi_rx_ring_t *ring;
948 	wpi_rx_data_t *data;
949 	int i, err = DDI_SUCCESS;
950 
951 	ring = &sc->sc_rxq;
952 	ring->cur = 0;
953 
954 	err = wpi_alloc_dma_mem(sc, WPI_RX_RING_COUNT * sizeof (uint32_t),
955 	    &ring_desc_dma_attr, &wpi_dma_accattr,
956 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
957 	    &ring->dma_desc);
958 	if (err != DDI_SUCCESS) {
959 		WPI_DBG((WPI_DEBUG_DMA, "dma alloc rx ring desc failed\n"));
960 		goto fail;
961 	}
962 	ring->desc = (uint32_t *)ring->dma_desc.mem_va;
963 
964 	/*
965 	 * Allocate Rx buffers.
966 	 */
967 	for (i = 0; i < WPI_RX_RING_COUNT; i++) {
968 		data = &ring->data[i];
969 		err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz,
970 		    &rx_buffer_dma_attr, &wpi_dma_accattr,
971 		    DDI_DMA_READ | DDI_DMA_STREAMING,
972 		    &data->dma_data);
973 		if (err != DDI_SUCCESS) {
974 			WPI_DBG((WPI_DEBUG_DMA, "dma alloc rx ring buf[%d] "
975 			    "failed\n", i));
976 			goto fail;
977 		}
978 
979 		ring->desc[i] = LE_32(data->dma_data.cookie.dmac_address);
980 	}
981 
982 	WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
983 
984 	return (err);
985 
986 fail:
987 	wpi_free_rx_ring(sc);
988 	return (err);
989 }
990 
991 static void
992 wpi_reset_rx_ring(wpi_sc_t *sc)
993 {
994 	int ntries;
995 
996 	wpi_mem_lock(sc);
997 
998 	WPI_WRITE(sc, WPI_RX_CONFIG, 0);
999 	for (ntries = 0; ntries < 2000; ntries++) {
1000 		if (WPI_READ(sc, WPI_RX_STATUS) & WPI_RX_IDLE)
1001 			break;
1002 		DELAY(1000);
1003 	}
1004 	if (ntries == 2000)
1005 		WPI_DBG((WPI_DEBUG_DMA, "timeout resetting Rx ring\n"));
1006 
1007 	wpi_mem_unlock(sc);
1008 
1009 	sc->sc_rxq.cur = 0;
1010 }
1011 
1012 static void
1013 wpi_free_rx_ring(wpi_sc_t *sc)
1014 {
1015 	int i;
1016 
1017 	for (i = 0; i < WPI_RX_RING_COUNT; i++) {
1018 		if (sc->sc_rxq.data[i].dma_data.dma_hdl)
1019 			WPI_DMA_SYNC(sc->sc_rxq.data[i].dma_data,
1020 			    DDI_DMA_SYNC_FORCPU);
1021 		wpi_free_dma_mem(&sc->sc_rxq.data[i].dma_data);
1022 	}
1023 
1024 	if (sc->sc_rxq.dma_desc.dma_hdl)
1025 		WPI_DMA_SYNC(sc->sc_rxq.dma_desc, DDI_DMA_SYNC_FORDEV);
1026 	wpi_free_dma_mem(&sc->sc_rxq.dma_desc);
1027 }
1028 
1029 static int
1030 wpi_alloc_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring, int count, int qid)
1031 {
1032 	wpi_tx_data_t *data;
1033 	wpi_tx_desc_t *desc_h;
1034 	uint32_t paddr_desc_h;
1035 	wpi_tx_cmd_t *cmd_h;
1036 	uint32_t paddr_cmd_h;
1037 	int i, err = DDI_SUCCESS;
1038 
1039 	ring->qid = qid;
1040 	ring->count = count;
1041 	ring->queued = 0;
1042 	ring->cur = 0;
1043 
1044 	err = wpi_alloc_dma_mem(sc, count * sizeof (wpi_tx_desc_t),
1045 	    &ring_desc_dma_attr, &wpi_dma_accattr,
1046 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1047 	    &ring->dma_desc);
1048 	if (err != DDI_SUCCESS) {
1049 		WPI_DBG((WPI_DEBUG_DMA, "dma alloc tx ring desc[%d] failed\n",
1050 		    qid));
1051 		goto fail;
1052 	}
1053 
1054 	/* update shared page with ring's base address */
1055 	sc->sc_shared->txbase[qid] = ring->dma_desc.cookie.dmac_address;
1056 
1057 	desc_h = (wpi_tx_desc_t *)ring->dma_desc.mem_va;
1058 	paddr_desc_h = ring->dma_desc.cookie.dmac_address;
1059 
1060 	err = wpi_alloc_dma_mem(sc, count * sizeof (wpi_tx_cmd_t),
1061 	    &tx_cmd_dma_attr, &wpi_dma_accattr,
1062 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1063 	    &ring->dma_cmd);
1064 	if (err != DDI_SUCCESS) {
1065 		WPI_DBG((WPI_DEBUG_DMA, "dma alloc tx ring cmd[%d] failed\n",
1066 		    qid));
1067 		goto fail;
1068 	}
1069 
1070 	cmd_h = (wpi_tx_cmd_t *)ring->dma_cmd.mem_va;
1071 	paddr_cmd_h = ring->dma_cmd.cookie.dmac_address;
1072 
1073 	/*
1074 	 * Allocate Tx buffers.
1075 	 */
1076 	ring->data = kmem_zalloc(sizeof (wpi_tx_data_t) * count, KM_NOSLEEP);
1077 	if (ring->data == NULL) {
1078 		WPI_DBG((WPI_DEBUG_DMA, "could not allocate tx data slots\n"));
1079 		goto fail;
1080 	}
1081 
1082 	for (i = 0; i < count; i++) {
1083 		data = &ring->data[i];
1084 		err = wpi_alloc_dma_mem(sc, sc->sc_dmabuf_sz,
1085 		    &tx_buffer_dma_attr, &wpi_dma_accattr,
1086 		    DDI_DMA_WRITE | DDI_DMA_STREAMING,
1087 		    &data->dma_data);
1088 		if (err != DDI_SUCCESS) {
1089 			WPI_DBG((WPI_DEBUG_DMA, "dma alloc tx ring buf[%d] "
1090 			    "failed\n", i));
1091 			goto fail;
1092 		}
1093 
1094 		data->desc = desc_h + i;
1095 		data->paddr_desc = paddr_desc_h +
1096 		    ((uintptr_t)data->desc - (uintptr_t)desc_h);
1097 		data->cmd = cmd_h + i;
1098 		data->paddr_cmd = paddr_cmd_h +
1099 		    ((uintptr_t)data->cmd - (uintptr_t)cmd_h);
1100 	}
1101 
1102 	return (err);
1103 
1104 fail:
1105 	wpi_free_tx_ring(sc, ring);
1106 	return (err);
1107 }
1108 
1109 static void
1110 wpi_reset_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring)
1111 {
1112 	wpi_tx_data_t *data;
1113 	int i, ntries;
1114 
1115 	wpi_mem_lock(sc);
1116 
1117 	WPI_WRITE(sc, WPI_TX_CONFIG(ring->qid), 0);
1118 	for (ntries = 0; ntries < 100; ntries++) {
1119 		if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(ring->qid))
1120 			break;
1121 		DELAY(10);
1122 	}
1123 #ifdef DEBUG
1124 	if (ntries == 100 && wpi_dbg_flags > 0) {
1125 		WPI_DBG((WPI_DEBUG_DMA, "timeout resetting Tx ring %d\n",
1126 		    ring->qid));
1127 	}
1128 #endif
1129 	wpi_mem_unlock(sc);
1130 
1131 	if (!(sc->sc_flags & WPI_F_QUIESCED)) {
1132 		for (i = 0; i < ring->count; i++) {
1133 			data = &ring->data[i];
1134 			WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
1135 		}
1136 	}
1137 
1138 	ring->queued = 0;
1139 	ring->cur = 0;
1140 }
1141 
1142 /*ARGSUSED*/
1143 static void
1144 wpi_free_tx_ring(wpi_sc_t *sc, wpi_tx_ring_t *ring)
1145 {
1146 	int i;
1147 
1148 	if (ring->dma_desc.dma_hdl != NULL)
1149 		WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
1150 	wpi_free_dma_mem(&ring->dma_desc);
1151 
1152 	if (ring->dma_cmd.dma_hdl != NULL)
1153 		WPI_DMA_SYNC(ring->dma_cmd, DDI_DMA_SYNC_FORDEV);
1154 	wpi_free_dma_mem(&ring->dma_cmd);
1155 
1156 	if (ring->data != NULL) {
1157 		for (i = 0; i < ring->count; i++) {
1158 			if (ring->data[i].dma_data.dma_hdl)
1159 				WPI_DMA_SYNC(ring->data[i].dma_data,
1160 				    DDI_DMA_SYNC_FORDEV);
1161 			wpi_free_dma_mem(&ring->data[i].dma_data);
1162 		}
1163 		kmem_free(ring->data, ring->count * sizeof (wpi_tx_data_t));
1164 		ring->data = NULL;
1165 	}
1166 }
1167 
1168 static int
1169 wpi_ring_init(wpi_sc_t *sc)
1170 {
1171 	int i, err = DDI_SUCCESS;
1172 
1173 	for (i = 0; i < 4; i++) {
1174 		err = wpi_alloc_tx_ring(sc, &sc->sc_txq[i], WPI_TX_RING_COUNT,
1175 		    i);
1176 		if (err != DDI_SUCCESS)
1177 			goto fail;
1178 	}
1179 	err = wpi_alloc_tx_ring(sc, &sc->sc_cmdq, WPI_CMD_RING_COUNT, 4);
1180 	if (err != DDI_SUCCESS)
1181 		goto fail;
1182 	err = wpi_alloc_tx_ring(sc, &sc->sc_svcq, WPI_SVC_RING_COUNT, 5);
1183 	if (err != DDI_SUCCESS)
1184 		goto fail;
1185 	err = wpi_alloc_rx_ring(sc);
1186 	if (err != DDI_SUCCESS)
1187 		goto fail;
1188 	return (err);
1189 
1190 fail:
1191 	return (err);
1192 }
1193 
1194 static void
1195 wpi_ring_free(wpi_sc_t *sc)
1196 {
1197 	int i = 4;
1198 
1199 	wpi_free_rx_ring(sc);
1200 	wpi_free_tx_ring(sc, &sc->sc_svcq);
1201 	wpi_free_tx_ring(sc, &sc->sc_cmdq);
1202 	while (--i >= 0) {
1203 		wpi_free_tx_ring(sc, &sc->sc_txq[i]);
1204 	}
1205 }
1206 
1207 /* ARGSUSED */
1208 static ieee80211_node_t *
1209 wpi_node_alloc(ieee80211com_t *ic)
1210 {
1211 	wpi_amrr_t *amrr;
1212 
1213 	amrr = kmem_zalloc(sizeof (wpi_amrr_t), KM_SLEEP);
1214 	if (amrr != NULL)
1215 		wpi_amrr_init(amrr);
1216 	return (&amrr->in);
1217 }
1218 
1219 static void
1220 wpi_node_free(ieee80211_node_t *in)
1221 {
1222 	ieee80211com_t *ic = in->in_ic;
1223 
1224 	ic->ic_node_cleanup(in);
1225 	if (in->in_wpa_ie != NULL)
1226 		ieee80211_free(in->in_wpa_ie);
1227 	kmem_free(in, sizeof (wpi_amrr_t));
1228 }
1229 
1230 /*ARGSUSED*/
1231 static int
1232 wpi_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
1233 {
1234 	wpi_sc_t *sc = (wpi_sc_t *)ic;
1235 	ieee80211_node_t *in = ic->ic_bss;
1236 	enum ieee80211_state ostate;
1237 	int i, err = WPI_SUCCESS;
1238 
1239 	mutex_enter(&sc->sc_glock);
1240 	ostate = ic->ic_state;
1241 	switch (nstate) {
1242 	case IEEE80211_S_SCAN:
1243 		switch (ostate) {
1244 		case IEEE80211_S_INIT:
1245 		{
1246 			wpi_node_t node;
1247 
1248 			sc->sc_flags |= WPI_F_SCANNING;
1249 			sc->sc_scan_next = 0;
1250 
1251 			/* make the link LED blink while we're scanning */
1252 			wpi_set_led(sc, WPI_LED_LINK, 20, 2);
1253 
1254 			/*
1255 			 * clear association to receive beacons from all
1256 			 * BSS'es
1257 			 */
1258 			sc->sc_config.state = 0;
1259 			sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
1260 
1261 			WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x "
1262 			    "filter %x\n",
1263 			    sc->sc_config.chan, sc->sc_config.flags,
1264 			    sc->sc_config.filter));
1265 
1266 			err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
1267 			    sizeof (wpi_config_t), 1);
1268 			if (err != WPI_SUCCESS) {
1269 				cmn_err(CE_WARN,
1270 				    "could not clear association\n");
1271 				sc->sc_flags &= ~WPI_F_SCANNING;
1272 				mutex_exit(&sc->sc_glock);
1273 				return (err);
1274 			}
1275 
1276 			/* add broadcast node to send probe request */
1277 			(void) memset(&node, 0, sizeof (node));
1278 			(void) memset(&node.bssid, 0xff, IEEE80211_ADDR_LEN);
1279 			node.id = WPI_ID_BROADCAST;
1280 
1281 			err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node,
1282 			    sizeof (node), 1);
1283 			if (err != WPI_SUCCESS) {
1284 				cmn_err(CE_WARN,
1285 				    "could not add broadcast node\n");
1286 				sc->sc_flags &= ~WPI_F_SCANNING;
1287 				mutex_exit(&sc->sc_glock);
1288 				return (err);
1289 			}
1290 			break;
1291 		}
1292 		case IEEE80211_S_SCAN:
1293 			mutex_exit(&sc->sc_glock);
1294 			/* step to next channel before actual FW scan */
1295 			err = sc->sc_newstate(ic, nstate, arg);
1296 			mutex_enter(&sc->sc_glock);
1297 			if ((err != 0) || ((err = wpi_scan(sc)) != 0)) {
1298 				cmn_err(CE_WARN,
1299 				    "could not initiate scan\n");
1300 				sc->sc_flags &= ~WPI_F_SCANNING;
1301 				ieee80211_cancel_scan(ic);
1302 			}
1303 			mutex_exit(&sc->sc_glock);
1304 			return (err);
1305 		default:
1306 			break;
1307 		}
1308 		sc->sc_clk = 0;
1309 		break;
1310 
1311 	case IEEE80211_S_AUTH:
1312 		if (ostate == IEEE80211_S_SCAN) {
1313 			sc->sc_flags &= ~WPI_F_SCANNING;
1314 		}
1315 
1316 		/* reset state to handle reassociations correctly */
1317 		sc->sc_config.state = 0;
1318 		sc->sc_config.filter &= ~LE_32(WPI_FILTER_BSS);
1319 
1320 		if ((err = wpi_auth(sc)) != 0) {
1321 			WPI_DBG((WPI_DEBUG_80211,
1322 			    "could not send authentication request\n"));
1323 			mutex_exit(&sc->sc_glock);
1324 			return (err);
1325 		}
1326 		break;
1327 
1328 	case IEEE80211_S_RUN:
1329 		if (ostate == IEEE80211_S_SCAN) {
1330 			sc->sc_flags &= ~WPI_F_SCANNING;
1331 		}
1332 
1333 		if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1334 			/* link LED blinks while monitoring */
1335 			wpi_set_led(sc, WPI_LED_LINK, 5, 5);
1336 			break;
1337 		}
1338 
1339 		if (ic->ic_opmode != IEEE80211_M_STA) {
1340 			(void) wpi_auth(sc);
1341 			/* need setup beacon here */
1342 		}
1343 		WPI_DBG((WPI_DEBUG_80211, "wpi: associated."));
1344 
1345 		/* update adapter's configuration */
1346 		sc->sc_config.state = LE_16(WPI_CONFIG_ASSOCIATED);
1347 		/* short preamble/slot time are negotiated when associating */
1348 		sc->sc_config.flags &= ~LE_32(WPI_CONFIG_SHPREAMBLE |
1349 		    WPI_CONFIG_SHSLOT);
1350 		if (ic->ic_flags & IEEE80211_F_SHSLOT)
1351 			sc->sc_config.flags |= LE_32(WPI_CONFIG_SHSLOT);
1352 		if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1353 			sc->sc_config.flags |= LE_32(WPI_CONFIG_SHPREAMBLE);
1354 		sc->sc_config.filter |= LE_32(WPI_FILTER_BSS);
1355 		if (ic->ic_opmode != IEEE80211_M_STA)
1356 			sc->sc_config.filter |= LE_32(WPI_FILTER_BEACON);
1357 
1358 		WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x\n",
1359 		    sc->sc_config.chan, sc->sc_config.flags));
1360 		err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
1361 		    sizeof (wpi_config_t), 1);
1362 		if (err != WPI_SUCCESS) {
1363 			WPI_DBG((WPI_DEBUG_80211,
1364 			    "could not update configuration\n"));
1365 			mutex_exit(&sc->sc_glock);
1366 			return (err);
1367 		}
1368 
1369 		/* start automatic rate control */
1370 		mutex_enter(&sc->sc_mt_lock);
1371 		if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
1372 			sc->sc_flags |= WPI_F_RATE_AUTO_CTL;
1373 			/* set rate to some reasonable initial value */
1374 			i = in->in_rates.ir_nrates - 1;
1375 			while (i > 0 && IEEE80211_RATE(i) > 72)
1376 				i--;
1377 			in->in_txrate = i;
1378 		} else {
1379 			sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
1380 		}
1381 		mutex_exit(&sc->sc_mt_lock);
1382 
1383 		/* link LED always on while associated */
1384 		wpi_set_led(sc, WPI_LED_LINK, 0, 1);
1385 		break;
1386 
1387 	case IEEE80211_S_INIT:
1388 		sc->sc_flags &= ~WPI_F_SCANNING;
1389 		break;
1390 
1391 	case IEEE80211_S_ASSOC:
1392 		sc->sc_flags &= ~WPI_F_SCANNING;
1393 		break;
1394 	}
1395 
1396 	mutex_exit(&sc->sc_glock);
1397 	return (sc->sc_newstate(ic, nstate, arg));
1398 }
1399 
1400 /*ARGSUSED*/
1401 static int wpi_key_set(ieee80211com_t *ic, const struct ieee80211_key *k,
1402     const uint8_t mac[IEEE80211_ADDR_LEN])
1403 {
1404 	wpi_sc_t *sc = (wpi_sc_t *)ic;
1405 	wpi_node_t node;
1406 	int err;
1407 
1408 	switch (k->wk_cipher->ic_cipher) {
1409 	case IEEE80211_CIPHER_WEP:
1410 	case IEEE80211_CIPHER_TKIP:
1411 		return (1); /* sofeware do it. */
1412 	case IEEE80211_CIPHER_AES_CCM:
1413 		break;
1414 	default:
1415 		return (0);
1416 	}
1417 	sc->sc_config.filter &= ~(WPI_FILTER_NODECRYPTUNI |
1418 	    WPI_FILTER_NODECRYPTMUL);
1419 
1420 	mutex_enter(&sc->sc_glock);
1421 
1422 	/* update ap/multicast node */
1423 	(void) memset(&node, 0, sizeof (node));
1424 	if (IEEE80211_IS_MULTICAST(mac)) {
1425 		(void) memset(node.bssid, 0xff, 6);
1426 		node.id = WPI_ID_BROADCAST;
1427 	} else {
1428 		IEEE80211_ADDR_COPY(node.bssid, ic->ic_bss->in_bssid);
1429 		node.id = WPI_ID_BSS;
1430 	}
1431 	if (k->wk_flags & IEEE80211_KEY_XMIT) {
1432 		node.key_flags = 0;
1433 		node.keyp = k->wk_keyix;
1434 	} else {
1435 		node.key_flags = (1 << 14);
1436 		node.keyp = k->wk_keyix + 4;
1437 	}
1438 	(void) memcpy(node.key, k->wk_key, k->wk_keylen);
1439 	node.key_flags |= (2 | (1 << 3) | (k->wk_keyix << 8));
1440 	node.sta_mask = 1;
1441 	node.control = 1;
1442 	err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 1);
1443 	if (err != WPI_SUCCESS) {
1444 		cmn_err(CE_WARN, "wpi_key_set():"
1445 		    "failed to update ap node\n");
1446 		mutex_exit(&sc->sc_glock);
1447 		return (0);
1448 	}
1449 	mutex_exit(&sc->sc_glock);
1450 	return (1);
1451 }
1452 
1453 /*
1454  * Grab exclusive access to NIC memory.
1455  */
1456 static void
1457 wpi_mem_lock(wpi_sc_t *sc)
1458 {
1459 	uint32_t tmp;
1460 	int ntries;
1461 
1462 	tmp = WPI_READ(sc, WPI_GPIO_CTL);
1463 	WPI_WRITE(sc, WPI_GPIO_CTL, tmp | WPI_GPIO_MAC);
1464 
1465 	/* spin until we actually get the lock */
1466 	for (ntries = 0; ntries < 1000; ntries++) {
1467 		if ((WPI_READ(sc, WPI_GPIO_CTL) &
1468 		    (WPI_GPIO_CLOCK | WPI_GPIO_SLEEP)) == WPI_GPIO_CLOCK)
1469 			break;
1470 		DELAY(10);
1471 	}
1472 	if (ntries == 1000)
1473 		WPI_DBG((WPI_DEBUG_PIO, "could not lock memory\n"));
1474 }
1475 
1476 /*
1477  * Release lock on NIC memory.
1478  */
1479 static void
1480 wpi_mem_unlock(wpi_sc_t *sc)
1481 {
1482 	uint32_t tmp = WPI_READ(sc, WPI_GPIO_CTL);
1483 	WPI_WRITE(sc, WPI_GPIO_CTL, tmp & ~WPI_GPIO_MAC);
1484 }
1485 
1486 static uint32_t
1487 wpi_mem_read(wpi_sc_t *sc, uint16_t addr)
1488 {
1489 	WPI_WRITE(sc, WPI_READ_MEM_ADDR, WPI_MEM_4 | addr);
1490 	return (WPI_READ(sc, WPI_READ_MEM_DATA));
1491 }
1492 
1493 static void
1494 wpi_mem_write(wpi_sc_t *sc, uint16_t addr, uint32_t data)
1495 {
1496 	WPI_WRITE(sc, WPI_WRITE_MEM_ADDR, WPI_MEM_4 | addr);
1497 	WPI_WRITE(sc, WPI_WRITE_MEM_DATA, data);
1498 }
1499 
1500 static void
1501 wpi_mem_write_region_4(wpi_sc_t *sc, uint16_t addr,
1502     const uint32_t *data, int wlen)
1503 {
1504 	for (; wlen > 0; wlen--, data++, addr += 4)
1505 		wpi_mem_write(sc, addr, *data);
1506 }
1507 
1508 /*
1509  * Read 16 bits from the EEPROM.  We access EEPROM through the MAC instead of
1510  * using the traditional bit-bang method.
1511  */
1512 static uint16_t
1513 wpi_read_prom_word(wpi_sc_t *sc, uint32_t addr)
1514 {
1515 	uint32_t val;
1516 	int ntries;
1517 
1518 	WPI_WRITE(sc, WPI_EEPROM_CTL, addr << 2);
1519 
1520 	wpi_mem_lock(sc);
1521 	for (ntries = 0; ntries < 10; ntries++) {
1522 		if ((val = WPI_READ(sc, WPI_EEPROM_CTL)) & WPI_EEPROM_READY)
1523 			break;
1524 		DELAY(10);
1525 	}
1526 	wpi_mem_unlock(sc);
1527 
1528 	if (ntries == 10) {
1529 		WPI_DBG((WPI_DEBUG_PIO, "could not read EEPROM\n"));
1530 		return (0xdead);
1531 	}
1532 	return (val >> 16);
1533 }
1534 
1535 /*
1536  * The firmware boot code is small and is intended to be copied directly into
1537  * the NIC internal memory.
1538  */
1539 static int
1540 wpi_load_microcode(wpi_sc_t *sc)
1541 {
1542 	const char *ucode;
1543 	int size;
1544 
1545 	ucode = sc->sc_boot;
1546 	size = LE_32(sc->sc_hdr->bootsz);
1547 	/* check that microcode size is a multiple of 4 */
1548 	if (size & 3)
1549 		return (EINVAL);
1550 
1551 	size /= sizeof (uint32_t);
1552 
1553 	wpi_mem_lock(sc);
1554 
1555 	/* copy microcode image into NIC memory */
1556 	wpi_mem_write_region_4(sc, WPI_MEM_UCODE_BASE, (const uint32_t *)ucode,
1557 	    size);
1558 
1559 	wpi_mem_write(sc, WPI_MEM_UCODE_SRC, 0);
1560 	wpi_mem_write(sc, WPI_MEM_UCODE_DST, WPI_FW_TEXT);
1561 	wpi_mem_write(sc, WPI_MEM_UCODE_SIZE, size);
1562 
1563 	/* run microcode */
1564 	wpi_mem_write(sc, WPI_MEM_UCODE_CTL, WPI_UC_RUN);
1565 
1566 	wpi_mem_unlock(sc);
1567 
1568 	return (WPI_SUCCESS);
1569 }
1570 
1571 /*
1572  * The firmware text and data segments are transferred to the NIC using DMA.
1573  * The driver just copies the firmware into DMA-safe memory and tells the NIC
1574  * where to find it.  Once the NIC has copied the firmware into its internal
1575  * memory, we can free our local copy in the driver.
1576  */
1577 static int
1578 wpi_load_firmware(wpi_sc_t *sc, uint32_t target)
1579 {
1580 	const char *fw;
1581 	int size;
1582 	wpi_dma_t *dma_p;
1583 	ddi_dma_cookie_t *cookie;
1584 	wpi_tx_desc_t desc;
1585 	int i, ntries, err = WPI_SUCCESS;
1586 
1587 	/* only text and data here */
1588 	if (target == WPI_FW_TEXT) {
1589 		fw = sc->sc_text;
1590 		size = LE_32(sc->sc_hdr->textsz);
1591 		dma_p = &sc->sc_dma_fw_text;
1592 		cookie = sc->sc_fw_text_cookie;
1593 	} else {
1594 		fw = sc->sc_data;
1595 		size = LE_32(sc->sc_hdr->datasz);
1596 		dma_p = &sc->sc_dma_fw_data;
1597 		cookie = sc->sc_fw_data_cookie;
1598 	}
1599 
1600 	/* copy firmware image to DMA-safe memory */
1601 	(void) memcpy(dma_p->mem_va, fw, size);
1602 
1603 	/* make sure the adapter will get up-to-date values */
1604 	(void) ddi_dma_sync(dma_p->dma_hdl, 0, size, DDI_DMA_SYNC_FORDEV);
1605 
1606 	(void) memset(&desc, 0, sizeof (desc));
1607 	desc.flags = LE_32(WPI_PAD32(size) << 28 | dma_p->ncookies << 24);
1608 	for (i = 0; i < dma_p->ncookies; i++) {
1609 		WPI_DBG((WPI_DEBUG_DMA, "cookie%d addr:%x size:%x\n",
1610 		    i, cookie[i].dmac_address, cookie[i].dmac_size));
1611 		desc.segs[i].addr = cookie[i].dmac_address;
1612 		desc.segs[i].len = (uint32_t)cookie[i].dmac_size;
1613 	}
1614 
1615 	wpi_mem_lock(sc);
1616 
1617 	/* tell adapter where to copy image in its internal memory */
1618 	WPI_WRITE(sc, WPI_FW_TARGET, target);
1619 
1620 	WPI_WRITE(sc, WPI_TX_CONFIG(6), 0);
1621 
1622 	/* copy firmware descriptor into NIC memory */
1623 	WPI_WRITE_REGION_4(sc, WPI_TX_DESC(6), (uint32_t *)&desc,
1624 	    sizeof desc / sizeof (uint32_t));
1625 
1626 	WPI_WRITE(sc, WPI_TX_CREDIT(6), 0xfffff);
1627 	WPI_WRITE(sc, WPI_TX_STATE(6), 0x4001);
1628 	WPI_WRITE(sc, WPI_TX_CONFIG(6), 0x80000001);
1629 
1630 	/* wait while the adapter is busy copying the firmware */
1631 	for (ntries = 0; ntries < 100; ntries++) {
1632 		if (WPI_READ(sc, WPI_TX_STATUS) & WPI_TX_IDLE(6))
1633 			break;
1634 		DELAY(1000);
1635 	}
1636 	if (ntries == 100) {
1637 		WPI_DBG((WPI_DEBUG_FW, "timeout transferring firmware\n"));
1638 		err = ETIMEDOUT;
1639 	}
1640 
1641 	WPI_WRITE(sc, WPI_TX_CREDIT(6), 0);
1642 
1643 	wpi_mem_unlock(sc);
1644 
1645 	return (err);
1646 }
1647 
1648 /*ARGSUSED*/
1649 static void
1650 wpi_rx_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc, wpi_rx_data_t *data)
1651 {
1652 	ieee80211com_t *ic = &sc->sc_ic;
1653 	wpi_rx_ring_t *ring = &sc->sc_rxq;
1654 	wpi_rx_stat_t *stat;
1655 	wpi_rx_head_t *head;
1656 	wpi_rx_tail_t *tail;
1657 	ieee80211_node_t *in;
1658 	struct ieee80211_frame *wh;
1659 	mblk_t *mp;
1660 	uint16_t len;
1661 
1662 	stat = (wpi_rx_stat_t *)(desc + 1);
1663 
1664 	if (stat->len > WPI_STAT_MAXLEN) {
1665 		WPI_DBG((WPI_DEBUG_RX, "invalid rx statistic header\n"));
1666 		return;
1667 	}
1668 
1669 	head = (wpi_rx_head_t *)((caddr_t)(stat + 1) + stat->len);
1670 	tail = (wpi_rx_tail_t *)((caddr_t)(head + 1) + LE_16(head->len));
1671 
1672 	len = LE_16(head->len);
1673 
1674 	WPI_DBG((WPI_DEBUG_RX, "rx intr: idx=%d len=%d stat len=%d rssi=%d "
1675 	    "rate=%x chan=%d tstamp=%llu", ring->cur, LE_32(desc->len),
1676 	    len, (int8_t)stat->rssi, head->rate, head->chan,
1677 	    LE_64(tail->tstamp)));
1678 
1679 	if ((len < 20) || (len > sc->sc_dmabuf_sz)) {
1680 		sc->sc_rx_err++;
1681 		return;
1682 	}
1683 
1684 	/*
1685 	 * Discard Rx frames with bad CRC early
1686 	 */
1687 	if ((LE_32(tail->flags) & WPI_RX_NOERROR) != WPI_RX_NOERROR) {
1688 		WPI_DBG((WPI_DEBUG_RX, "rx tail flags error %x\n",
1689 		    LE_32(tail->flags)));
1690 		sc->sc_rx_err++;
1691 		return;
1692 	}
1693 
1694 	/* update Rx descriptor */
1695 	/* ring->desc[ring->cur] = LE_32(data->dma_data.cookie.dmac_address); */
1696 
1697 #ifdef WPI_BPF
1698 #ifndef WPI_CURRENT
1699 	if (sc->sc_drvbpf != NULL) {
1700 #else
1701 	if (bpf_peers_present(sc->sc_drvbpf)) {
1702 #endif
1703 		struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
1704 
1705 		tap->wr_flags = 0;
1706 		tap->wr_rate = head->rate;
1707 		tap->wr_chan_freq =
1708 		    LE_16(ic->ic_channels[head->chan].ic_freq);
1709 		tap->wr_chan_flags =
1710 		    LE_16(ic->ic_channels[head->chan].ic_flags);
1711 		tap->wr_dbm_antsignal = (int8_t)(stat->rssi - WPI_RSSI_OFFSET);
1712 		tap->wr_dbm_antnoise = (int8_t)LE_16(stat->noise);
1713 		tap->wr_tsft = tail->tstamp;
1714 		tap->wr_antenna = (LE_16(head->flags) >> 4) & 0xf;
1715 		switch (head->rate) {
1716 		/* CCK rates */
1717 		case  10: tap->wr_rate =   2; break;
1718 		case  20: tap->wr_rate =   4; break;
1719 		case  55: tap->wr_rate =  11; break;
1720 		case 110: tap->wr_rate =  22; break;
1721 		/* OFDM rates */
1722 		case 0xd: tap->wr_rate =  12; break;
1723 		case 0xf: tap->wr_rate =  18; break;
1724 		case 0x5: tap->wr_rate =  24; break;
1725 		case 0x7: tap->wr_rate =  36; break;
1726 		case 0x9: tap->wr_rate =  48; break;
1727 		case 0xb: tap->wr_rate =  72; break;
1728 		case 0x1: tap->wr_rate =  96; break;
1729 		case 0x3: tap->wr_rate = 108; break;
1730 		/* unknown rate: should not happen */
1731 		default:  tap->wr_rate =   0;
1732 		}
1733 		if (LE_16(head->flags) & 0x4)
1734 			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1735 
1736 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1737 	}
1738 #endif
1739 	/* grab a reference to the source node */
1740 	wh = (struct ieee80211_frame *)(head + 1);
1741 
1742 #ifdef DEBUG
1743 	if (wpi_dbg_flags & WPI_DEBUG_RX)
1744 		ieee80211_dump_pkt((uint8_t *)wh, len, 0, 0);
1745 #endif
1746 
1747 	in = ieee80211_find_rxnode(ic, wh);
1748 	mp = allocb(len, BPRI_MED);
1749 	if (mp) {
1750 		(void) memcpy(mp->b_wptr, wh, len);
1751 		mp->b_wptr += len;
1752 
1753 		/* send the frame to the 802.11 layer */
1754 		(void) ieee80211_input(ic, mp, in, stat->rssi, 0);
1755 	} else {
1756 		sc->sc_rx_nobuf++;
1757 		WPI_DBG((WPI_DEBUG_RX,
1758 		    "wpi_rx_intr(): alloc rx buf failed\n"));
1759 	}
1760 	/* release node reference */
1761 	ieee80211_free_node(in);
1762 }
1763 
1764 /*ARGSUSED*/
1765 static void
1766 wpi_tx_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc, wpi_rx_data_t *data)
1767 {
1768 	ieee80211com_t *ic = &sc->sc_ic;
1769 	wpi_tx_ring_t *ring = &sc->sc_txq[desc->qid & 0x3];
1770 	/* wpi_tx_data_t *txdata = &ring->data[desc->idx]; */
1771 	wpi_tx_stat_t *stat = (wpi_tx_stat_t *)(desc + 1);
1772 	wpi_amrr_t *amrr = (wpi_amrr_t *)ic->ic_bss;
1773 
1774 	WPI_DBG((WPI_DEBUG_TX, "tx done: qid=%d idx=%d retries=%d nkill=%d "
1775 	    "rate=%x duration=%d status=%x\n",
1776 	    desc->qid, desc->idx, stat->ntries, stat->nkill, stat->rate,
1777 	    LE_32(stat->duration), LE_32(stat->status)));
1778 
1779 	amrr->txcnt++;
1780 	WPI_DBG((WPI_DEBUG_RATECTL, "tx: %d cnt\n", amrr->txcnt));
1781 	if (stat->ntries > 0) {
1782 		amrr->retrycnt++;
1783 		sc->sc_tx_retries++;
1784 		WPI_DBG((WPI_DEBUG_RATECTL, "tx: %d retries\n",
1785 		    amrr->retrycnt));
1786 	}
1787 
1788 	sc->sc_tx_timer = 0;
1789 
1790 	mutex_enter(&sc->sc_tx_lock);
1791 	ring->queued--;
1792 	if (ring->queued < 0)
1793 		ring->queued = 0;
1794 	if ((sc->sc_need_reschedule) && (ring->queued <= (ring->count << 3))) {
1795 		sc->sc_need_reschedule = 0;
1796 		mutex_exit(&sc->sc_tx_lock);
1797 		mac_tx_update(ic->ic_mach);
1798 		mutex_enter(&sc->sc_tx_lock);
1799 	}
1800 	mutex_exit(&sc->sc_tx_lock);
1801 }
1802 
1803 static void
1804 wpi_cmd_intr(wpi_sc_t *sc, wpi_rx_desc_t *desc)
1805 {
1806 	if ((desc->qid & 7) != 4) {
1807 		return;	/* not a command ack */
1808 	}
1809 	mutex_enter(&sc->sc_glock);
1810 	sc->sc_flags |= WPI_F_CMD_DONE;
1811 	cv_signal(&sc->sc_cmd_cv);
1812 	mutex_exit(&sc->sc_glock);
1813 }
1814 
1815 static uint_t
1816 wpi_notif_softintr(caddr_t arg)
1817 {
1818 	wpi_sc_t *sc = (wpi_sc_t *)arg;
1819 	wpi_rx_desc_t *desc;
1820 	wpi_rx_data_t *data;
1821 	uint32_t hw;
1822 
1823 	mutex_enter(&sc->sc_glock);
1824 	if (sc->sc_notif_softint_pending != 1) {
1825 		mutex_exit(&sc->sc_glock);
1826 		return (DDI_INTR_UNCLAIMED);
1827 	}
1828 	mutex_exit(&sc->sc_glock);
1829 
1830 	hw = LE_32(sc->sc_shared->next);
1831 
1832 	while (sc->sc_rxq.cur != hw) {
1833 		data = &sc->sc_rxq.data[sc->sc_rxq.cur];
1834 		desc = (wpi_rx_desc_t *)data->dma_data.mem_va;
1835 
1836 		WPI_DBG((WPI_DEBUG_INTR, "rx notification hw = %d cur = %d "
1837 		    "qid=%x idx=%d flags=%x type=%d len=%d\n",
1838 		    hw, sc->sc_rxq.cur, desc->qid, desc->idx, desc->flags,
1839 		    desc->type, LE_32(desc->len)));
1840 
1841 		if (!(desc->qid & 0x80))	/* reply to a command */
1842 			wpi_cmd_intr(sc, desc);
1843 
1844 		switch (desc->type) {
1845 		case WPI_RX_DONE:
1846 			/* a 802.11 frame was received */
1847 			wpi_rx_intr(sc, desc, data);
1848 			break;
1849 
1850 		case WPI_TX_DONE:
1851 			/* a 802.11 frame has been transmitted */
1852 			wpi_tx_intr(sc, desc, data);
1853 			break;
1854 
1855 		case WPI_UC_READY:
1856 		{
1857 			wpi_ucode_info_t *uc =
1858 			    (wpi_ucode_info_t *)(desc + 1);
1859 
1860 			/* the microcontroller is ready */
1861 			WPI_DBG((WPI_DEBUG_FW,
1862 			    "microcode alive notification version %x "
1863 			    "alive %x\n", LE_32(uc->version),
1864 			    LE_32(uc->valid)));
1865 
1866 			if (LE_32(uc->valid) != 1) {
1867 				WPI_DBG((WPI_DEBUG_FW,
1868 				    "microcontroller initialization failed\n"));
1869 			}
1870 			break;
1871 		}
1872 		case WPI_STATE_CHANGED:
1873 		{
1874 			uint32_t *status = (uint32_t *)(desc + 1);
1875 
1876 			/* enabled/disabled notification */
1877 			WPI_DBG((WPI_DEBUG_RADIO, "state changed to %x\n",
1878 			    LE_32(*status)));
1879 
1880 			if (LE_32(*status) & 1) {
1881 				/*
1882 				 * the radio button has to be pushed(OFF). It
1883 				 * is considered as a hw error, the
1884 				 * wpi_thread() tries to recover it after the
1885 				 * button is pushed again(ON)
1886 				 */
1887 				cmn_err(CE_NOTE,
1888 				    "wpi: Radio transmitter is off\n");
1889 				sc->sc_ostate = sc->sc_ic.ic_state;
1890 				ieee80211_new_state(&sc->sc_ic,
1891 				    IEEE80211_S_INIT, -1);
1892 				sc->sc_flags |=
1893 				    (WPI_F_HW_ERR_RECOVER | WPI_F_RADIO_OFF);
1894 			}
1895 			break;
1896 		}
1897 		case WPI_START_SCAN:
1898 		{
1899 			wpi_start_scan_t *scan =
1900 			    (wpi_start_scan_t *)(desc + 1);
1901 
1902 			WPI_DBG((WPI_DEBUG_SCAN,
1903 			    "scanning channel %d status %x\n",
1904 			    scan->chan, LE_32(scan->status)));
1905 
1906 			break;
1907 		}
1908 		case WPI_STOP_SCAN:
1909 		{
1910 			wpi_stop_scan_t *scan =
1911 			    (wpi_stop_scan_t *)(desc + 1);
1912 
1913 			WPI_DBG((WPI_DEBUG_SCAN,
1914 			    "completed channel %d (burst of %d) status %02x\n",
1915 			    scan->chan, scan->nchan, scan->status));
1916 
1917 			sc->sc_scan_pending = 0;
1918 			sc->sc_scan_next++;
1919 			break;
1920 		}
1921 		default:
1922 			break;
1923 		}
1924 
1925 		sc->sc_rxq.cur = (sc->sc_rxq.cur + 1) % WPI_RX_RING_COUNT;
1926 	}
1927 
1928 	/* tell the firmware what we have processed */
1929 	hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
1930 	WPI_WRITE(sc, WPI_RX_WIDX, hw & (~7));
1931 	mutex_enter(&sc->sc_glock);
1932 	sc->sc_notif_softint_pending = 0;
1933 	mutex_exit(&sc->sc_glock);
1934 
1935 	return (DDI_INTR_CLAIMED);
1936 }
1937 
1938 static uint_t
1939 wpi_intr(caddr_t arg)
1940 {
1941 	wpi_sc_t *sc = (wpi_sc_t *)arg;
1942 	uint32_t r, rfh;
1943 
1944 	mutex_enter(&sc->sc_glock);
1945 	if (sc->sc_flags & WPI_F_SUSPEND) {
1946 		mutex_exit(&sc->sc_glock);
1947 		return (DDI_INTR_UNCLAIMED);
1948 	}
1949 
1950 	r = WPI_READ(sc, WPI_INTR);
1951 	if (r == 0 || r == 0xffffffff) {
1952 		mutex_exit(&sc->sc_glock);
1953 		return (DDI_INTR_UNCLAIMED);
1954 	}
1955 
1956 	WPI_DBG((WPI_DEBUG_INTR, "interrupt reg %x\n", r));
1957 
1958 	rfh = WPI_READ(sc, WPI_INTR_STATUS);
1959 	/* disable interrupts */
1960 	WPI_WRITE(sc, WPI_MASK, 0);
1961 	/* ack interrupts */
1962 	WPI_WRITE(sc, WPI_INTR, r);
1963 	WPI_WRITE(sc, WPI_INTR_STATUS, rfh);
1964 
1965 	if (sc->sc_notif_softint_id == NULL) {
1966 		mutex_exit(&sc->sc_glock);
1967 		return (DDI_INTR_CLAIMED);
1968 	}
1969 
1970 	if (r & (WPI_SW_ERROR | WPI_HW_ERROR)) {
1971 		WPI_DBG((WPI_DEBUG_FW, "fatal firmware error\n"));
1972 		mutex_exit(&sc->sc_glock);
1973 		wpi_stop(sc);
1974 		if (!(sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
1975 			sc->sc_ostate = sc->sc_ic.ic_state;
1976 		}
1977 		ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
1978 		sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
1979 		return (DDI_INTR_CLAIMED);
1980 	}
1981 
1982 	if ((r & (WPI_RX_INTR | WPI_RX_SWINT)) ||
1983 	    (rfh & 0x40070000)) {
1984 		sc->sc_notif_softint_pending = 1;
1985 		ddi_trigger_softintr(sc->sc_notif_softint_id);
1986 	}
1987 
1988 	if (r & WPI_ALIVE_INTR)	{ /* firmware initialized */
1989 		sc->sc_flags |= WPI_F_FW_INIT;
1990 		cv_signal(&sc->sc_fw_cv);
1991 	}
1992 
1993 	/* re-enable interrupts */
1994 	WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
1995 	mutex_exit(&sc->sc_glock);
1996 
1997 	return (DDI_INTR_CLAIMED);
1998 }
1999 
2000 static uint8_t
2001 wpi_plcp_signal(int rate)
2002 {
2003 	switch (rate) {
2004 	/* CCK rates (returned values are device-dependent) */
2005 	case 2:		return (10);
2006 	case 4:		return (20);
2007 	case 11:	return (55);
2008 	case 22:	return (110);
2009 
2010 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
2011 	/* R1-R4 (ral/ural is R4-R1) */
2012 	case 12:	return (0xd);
2013 	case 18:	return (0xf);
2014 	case 24:	return (0x5);
2015 	case 36:	return (0x7);
2016 	case 48:	return (0x9);
2017 	case 72:	return (0xb);
2018 	case 96:	return (0x1);
2019 	case 108:	return (0x3);
2020 
2021 	/* unsupported rates (should not get there) */
2022 	default:	return (0);
2023 	}
2024 }
2025 
2026 static mblk_t *
2027 wpi_m_tx(void *arg, mblk_t *mp)
2028 {
2029 	wpi_sc_t	*sc = (wpi_sc_t *)arg;
2030 	ieee80211com_t	*ic = &sc->sc_ic;
2031 	mblk_t			*next;
2032 
2033 	if (sc->sc_flags & WPI_F_SUSPEND) {
2034 		freemsgchain(mp);
2035 		return (NULL);
2036 	}
2037 
2038 	if (ic->ic_state != IEEE80211_S_RUN) {
2039 		freemsgchain(mp);
2040 		return (NULL);
2041 	}
2042 
2043 	while (mp != NULL) {
2044 		next = mp->b_next;
2045 		mp->b_next = NULL;
2046 		if (wpi_send(ic, mp, IEEE80211_FC0_TYPE_DATA) != 0) {
2047 			mp->b_next = next;
2048 			break;
2049 		}
2050 		mp = next;
2051 	}
2052 	return (mp);
2053 }
2054 
2055 /* ARGSUSED */
2056 static int
2057 wpi_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
2058 {
2059 	wpi_sc_t *sc = (wpi_sc_t *)ic;
2060 	wpi_tx_ring_t *ring;
2061 	wpi_tx_desc_t *desc;
2062 	wpi_tx_data_t *data;
2063 	wpi_tx_cmd_t *cmd;
2064 	wpi_cmd_data_t *tx;
2065 	ieee80211_node_t *in;
2066 	struct ieee80211_frame *wh;
2067 	struct ieee80211_key *k;
2068 	mblk_t *m, *m0;
2069 	int rate, hdrlen, len, mblen, off, err = WPI_SUCCESS;
2070 
2071 	ring = ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) ?
2072 	    (&sc->sc_txq[0]) : (&sc->sc_txq[1]);
2073 	data = &ring->data[ring->cur];
2074 	desc = data->desc;
2075 	cmd = data->cmd;
2076 	bzero(desc, sizeof (*desc));
2077 	bzero(cmd, sizeof (*cmd));
2078 
2079 	mutex_enter(&sc->sc_tx_lock);
2080 	if (sc->sc_flags & WPI_F_SUSPEND) {
2081 		mutex_exit(&sc->sc_tx_lock);
2082 		if ((type & IEEE80211_FC0_TYPE_MASK) !=
2083 		    IEEE80211_FC0_TYPE_DATA) {
2084 			freemsg(mp);
2085 		}
2086 		err = ENXIO;
2087 		goto exit;
2088 	}
2089 
2090 	if (ring->queued > ring->count - 64) {
2091 		WPI_DBG((WPI_DEBUG_TX, "wpi_send(): no txbuf\n"));
2092 		sc->sc_need_reschedule = 1;
2093 		mutex_exit(&sc->sc_tx_lock);
2094 		if ((type & IEEE80211_FC0_TYPE_MASK) !=
2095 		    IEEE80211_FC0_TYPE_DATA) {
2096 			freemsg(mp);
2097 		}
2098 		sc->sc_tx_nobuf++;
2099 		err = ENOMEM;
2100 		goto exit;
2101 	}
2102 	mutex_exit(&sc->sc_tx_lock);
2103 
2104 	hdrlen = sizeof (struct ieee80211_frame);
2105 
2106 	m = allocb(msgdsize(mp) + 32, BPRI_MED);
2107 	if (m == NULL) { /* can not alloc buf, drop this package */
2108 		cmn_err(CE_WARN,
2109 		    "wpi_send(): failed to allocate msgbuf\n");
2110 		freemsg(mp);
2111 		err = WPI_SUCCESS;
2112 		goto exit;
2113 	}
2114 	for (off = 0, m0 = mp; m0 != NULL; m0 = m0->b_cont) {
2115 		mblen = MBLKL(m0);
2116 		(void) memcpy(m->b_rptr + off, m0->b_rptr, mblen);
2117 		off += mblen;
2118 	}
2119 	m->b_wptr += off;
2120 	freemsg(mp);
2121 
2122 	wh = (struct ieee80211_frame *)m->b_rptr;
2123 
2124 	in = ieee80211_find_txnode(ic, wh->i_addr1);
2125 	if (in == NULL) {
2126 		cmn_err(CE_WARN, "wpi_send(): failed to find tx node\n");
2127 		freemsg(m);
2128 		sc->sc_tx_err++;
2129 		err = WPI_SUCCESS;
2130 		goto exit;
2131 	}
2132 
2133 	(void) ieee80211_encap(ic, m, in);
2134 
2135 	cmd->code = WPI_CMD_TX_DATA;
2136 	cmd->flags = 0;
2137 	cmd->qid = ring->qid;
2138 	cmd->idx = ring->cur;
2139 
2140 	tx = (wpi_cmd_data_t *)cmd->data;
2141 	tx->flags = 0;
2142 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2143 		tx->flags |= LE_32(WPI_TX_NEED_ACK);
2144 	} else {
2145 		tx->flags &= ~(LE_32(WPI_TX_NEED_ACK));
2146 	}
2147 
2148 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2149 		k = ieee80211_crypto_encap(ic, m);
2150 		if (k == NULL) {
2151 			freemsg(m);
2152 			sc->sc_tx_err++;
2153 			err = WPI_SUCCESS;
2154 			goto exit;
2155 		}
2156 
2157 		if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_AES_CCM) {
2158 			tx->security = 2; /* for CCMP */
2159 			tx->flags |= LE_32(WPI_TX_NEED_ACK);
2160 			(void) memcpy(&tx->key, k->wk_key, k->wk_keylen);
2161 		}
2162 
2163 		/* packet header may have moved, reset our local pointer */
2164 		wh = (struct ieee80211_frame *)m->b_rptr;
2165 	}
2166 
2167 	len = msgdsize(m);
2168 
2169 #ifdef DEBUG
2170 	if (wpi_dbg_flags & WPI_DEBUG_TX)
2171 		ieee80211_dump_pkt((uint8_t *)wh, hdrlen, 0, 0);
2172 #endif
2173 
2174 	/* pickup a rate */
2175 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2176 	    IEEE80211_FC0_TYPE_MGT) {
2177 		/* mgmt frames are sent at the lowest available bit-rate */
2178 		rate = 2;
2179 	} else {
2180 		if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
2181 			rate = ic->ic_fixed_rate;
2182 		} else
2183 			rate = in->in_rates.ir_rates[in->in_txrate];
2184 	}
2185 	rate &= IEEE80211_RATE_VAL;
2186 	WPI_DBG((WPI_DEBUG_RATECTL, "tx rate[%d of %d] = %x",
2187 	    in->in_txrate, in->in_rates.ir_nrates, rate));
2188 #ifdef WPI_BPF
2189 #ifndef WPI_CURRENT
2190 	if (sc->sc_drvbpf != NULL) {
2191 #else
2192 	if (bpf_peers_present(sc->sc_drvbpf)) {
2193 #endif
2194 		struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
2195 
2196 		tap->wt_flags = 0;
2197 		tap->wt_chan_freq = LE_16(ic->ic_curchan->ic_freq);
2198 		tap->wt_chan_flags = LE_16(ic->ic_curchan->ic_flags);
2199 		tap->wt_rate = rate;
2200 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
2201 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2202 
2203 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
2204 	}
2205 #endif
2206 
2207 	tx->flags |= (LE_32(WPI_TX_AUTO_SEQ));
2208 	tx->flags |= LE_32(WPI_TX_BT_DISABLE | WPI_TX_CALIBRATION);
2209 
2210 	/* retrieve destination node's id */
2211 	tx->id = IEEE80211_IS_MULTICAST(wh->i_addr1) ? WPI_ID_BROADCAST :
2212 	    WPI_ID_BSS;
2213 
2214 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2215 	    IEEE80211_FC0_TYPE_MGT) {
2216 		/* tell h/w to set timestamp in probe responses */
2217 		if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2218 		    IEEE80211_FC0_SUBTYPE_PROBE_RESP)
2219 			tx->flags |= LE_32(WPI_TX_INSERT_TSTAMP);
2220 
2221 		if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2222 		    IEEE80211_FC0_SUBTYPE_ASSOC_REQ) ||
2223 		    ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
2224 		    IEEE80211_FC0_SUBTYPE_REASSOC_REQ))
2225 			tx->timeout = 3;
2226 		else
2227 			tx->timeout = 2;
2228 	} else
2229 		tx->timeout = 0;
2230 
2231 	tx->rate = wpi_plcp_signal(rate);
2232 
2233 	/* be very persistant at sending frames out */
2234 	tx->rts_ntries = 7;
2235 	tx->data_ntries = 15;
2236 
2237 	tx->cck_mask  = 0x0f;
2238 	tx->ofdm_mask = 0xff;
2239 	tx->lifetime  = LE_32(0xffffffff);
2240 
2241 	tx->len = LE_16(len);
2242 
2243 	/* save and trim IEEE802.11 header */
2244 	(void) memcpy(tx + 1, m->b_rptr, hdrlen);
2245 	m->b_rptr += hdrlen;
2246 	(void) memcpy(data->dma_data.mem_va, m->b_rptr, len - hdrlen);
2247 
2248 	WPI_DBG((WPI_DEBUG_TX, "sending data: qid=%d idx=%d len=%d", ring->qid,
2249 	    ring->cur, len));
2250 
2251 	/* first scatter/gather segment is used by the tx data command */
2252 	desc->flags = LE_32(WPI_PAD32(len) << 28 | (2) << 24);
2253 	desc->segs[0].addr = LE_32(data->paddr_cmd);
2254 	desc->segs[0].len  = LE_32(
2255 	    roundup(4 + sizeof (wpi_cmd_data_t) + hdrlen, 4));
2256 	desc->segs[1].addr = LE_32(data->dma_data.cookie.dmac_address);
2257 	desc->segs[1].len  = LE_32(len - hdrlen);
2258 
2259 	WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
2260 	WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
2261 
2262 	mutex_enter(&sc->sc_tx_lock);
2263 	ring->queued++;
2264 	mutex_exit(&sc->sc_tx_lock);
2265 
2266 	/* kick ring */
2267 	ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT;
2268 	WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2269 	freemsg(m);
2270 	/* release node reference */
2271 	ieee80211_free_node(in);
2272 
2273 	ic->ic_stats.is_tx_bytes += len;
2274 	ic->ic_stats.is_tx_frags++;
2275 
2276 	if (sc->sc_tx_timer == 0)
2277 		sc->sc_tx_timer = 5;
2278 exit:
2279 	return (err);
2280 }
2281 
2282 static void
2283 wpi_m_ioctl(void* arg, queue_t *wq, mblk_t *mp)
2284 {
2285 	wpi_sc_t	*sc  = (wpi_sc_t *)arg;
2286 	ieee80211com_t	*ic = &sc->sc_ic;
2287 	int		err;
2288 
2289 	err = ieee80211_ioctl(ic, wq, mp);
2290 	if (err == ENETRESET) {
2291 		/*
2292 		 * This is special for the hidden AP connection.
2293 		 * In any case, we should make sure only one 'scan'
2294 		 * in the driver for a 'connect' CLI command. So
2295 		 * when connecting to a hidden AP, the scan is just
2296 		 * sent out to the air when we know the desired
2297 		 * essid of the AP we want to connect.
2298 		 */
2299 		if (ic->ic_des_esslen) {
2300 			if (sc->sc_flags & WPI_F_RUNNING) {
2301 				wpi_m_stop(sc);
2302 				(void) wpi_m_start(sc);
2303 				(void) ieee80211_new_state(ic,
2304 				    IEEE80211_S_SCAN, -1);
2305 			}
2306 		}
2307 	}
2308 }
2309 
2310 /*
2311  * Callback functions for get/set properties
2312  */
2313 /* ARGSUSED */
2314 static int
2315 wpi_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_name,
2316     uint_t pr_flags, uint_t wldp_length, void *wldp_buf, uint_t *perm)
2317 {
2318 	int		err = 0;
2319 	wpi_sc_t	*sc = (wpi_sc_t *)arg;
2320 
2321 	err = ieee80211_getprop(&sc->sc_ic, pr_name, wldp_pr_name,
2322 	    pr_flags, wldp_length, wldp_buf, perm);
2323 
2324 	return (err);
2325 }
2326 static int
2327 wpi_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_name,
2328     uint_t wldp_length, const void *wldp_buf)
2329 {
2330 	int		err;
2331 	wpi_sc_t	*sc = (wpi_sc_t *)arg;
2332 	ieee80211com_t  *ic = &sc->sc_ic;
2333 
2334 	err = ieee80211_setprop(ic, pr_name, wldp_pr_name,
2335 	    wldp_length, wldp_buf);
2336 
2337 	if (err == ENETRESET) {
2338 		if (ic->ic_des_esslen) {
2339 			if (sc->sc_flags & WPI_F_RUNNING) {
2340 				wpi_m_stop(sc);
2341 				(void) wpi_m_start(sc);
2342 				(void) ieee80211_new_state(ic,
2343 				    IEEE80211_S_SCAN, -1);
2344 			}
2345 		}
2346 
2347 		err = 0;
2348 	}
2349 
2350 	return (err);
2351 }
2352 
2353 /*ARGSUSED*/
2354 static int
2355 wpi_m_stat(void *arg, uint_t stat, uint64_t *val)
2356 {
2357 	wpi_sc_t	*sc  = (wpi_sc_t *)arg;
2358 	ieee80211com_t	*ic = &sc->sc_ic;
2359 	ieee80211_node_t *in;
2360 
2361 	mutex_enter(&sc->sc_glock);
2362 	switch (stat) {
2363 	case MAC_STAT_IFSPEED:
2364 		in = ic->ic_bss;
2365 		*val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ?
2366 		    IEEE80211_RATE(in->in_txrate) :
2367 		    ic->ic_fixed_rate) / 2 * 1000000;
2368 		break;
2369 	case MAC_STAT_NOXMTBUF:
2370 		*val = sc->sc_tx_nobuf;
2371 		break;
2372 	case MAC_STAT_NORCVBUF:
2373 		*val = sc->sc_rx_nobuf;
2374 		break;
2375 	case MAC_STAT_IERRORS:
2376 		*val = sc->sc_rx_err;
2377 		break;
2378 	case MAC_STAT_RBYTES:
2379 		*val = ic->ic_stats.is_rx_bytes;
2380 		break;
2381 	case MAC_STAT_IPACKETS:
2382 		*val = ic->ic_stats.is_rx_frags;
2383 		break;
2384 	case MAC_STAT_OBYTES:
2385 		*val = ic->ic_stats.is_tx_bytes;
2386 		break;
2387 	case MAC_STAT_OPACKETS:
2388 		*val = ic->ic_stats.is_tx_frags;
2389 		break;
2390 	case MAC_STAT_OERRORS:
2391 	case WIFI_STAT_TX_FAILED:
2392 		*val = sc->sc_tx_err;
2393 		break;
2394 	case WIFI_STAT_TX_RETRANS:
2395 		*val = sc->sc_tx_retries;
2396 		break;
2397 	case WIFI_STAT_FCS_ERRORS:
2398 	case WIFI_STAT_WEP_ERRORS:
2399 	case WIFI_STAT_TX_FRAGS:
2400 	case WIFI_STAT_MCAST_TX:
2401 	case WIFI_STAT_RTS_SUCCESS:
2402 	case WIFI_STAT_RTS_FAILURE:
2403 	case WIFI_STAT_ACK_FAILURE:
2404 	case WIFI_STAT_RX_FRAGS:
2405 	case WIFI_STAT_MCAST_RX:
2406 	case WIFI_STAT_RX_DUPS:
2407 		mutex_exit(&sc->sc_glock);
2408 		return (ieee80211_stat(ic, stat, val));
2409 	default:
2410 		mutex_exit(&sc->sc_glock);
2411 		return (ENOTSUP);
2412 	}
2413 	mutex_exit(&sc->sc_glock);
2414 
2415 	return (WPI_SUCCESS);
2416 
2417 }
2418 
2419 static int
2420 wpi_m_start(void *arg)
2421 {
2422 	wpi_sc_t *sc = (wpi_sc_t *)arg;
2423 	ieee80211com_t	*ic = &sc->sc_ic;
2424 	int err;
2425 
2426 	err = wpi_init(sc);
2427 	if (err != WPI_SUCCESS) {
2428 		wpi_stop(sc);
2429 		DELAY(1000000);
2430 		err = wpi_init(sc);
2431 	}
2432 
2433 	if (err) {
2434 		/*
2435 		 * The hw init err(eg. RF is OFF). Return Success to make
2436 		 * the 'plumb' succeed. The wpi_thread() tries to re-init
2437 		 * background.
2438 		 */
2439 		mutex_enter(&sc->sc_glock);
2440 		sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2441 		mutex_exit(&sc->sc_glock);
2442 		return (WPI_SUCCESS);
2443 	}
2444 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2445 	mutex_enter(&sc->sc_glock);
2446 	sc->sc_flags |= WPI_F_RUNNING;
2447 	mutex_exit(&sc->sc_glock);
2448 
2449 	return (WPI_SUCCESS);
2450 }
2451 
2452 static void
2453 wpi_m_stop(void *arg)
2454 {
2455 	wpi_sc_t *sc = (wpi_sc_t *)arg;
2456 	ieee80211com_t	*ic = &sc->sc_ic;
2457 
2458 	wpi_stop(sc);
2459 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2460 	mutex_enter(&sc->sc_mt_lock);
2461 	sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2462 	sc->sc_flags &= ~WPI_F_RATE_AUTO_CTL;
2463 	mutex_exit(&sc->sc_mt_lock);
2464 	mutex_enter(&sc->sc_glock);
2465 	sc->sc_flags &= ~WPI_F_RUNNING;
2466 	mutex_exit(&sc->sc_glock);
2467 }
2468 
2469 /*ARGSUSED*/
2470 static int
2471 wpi_m_unicst(void *arg, const uint8_t *macaddr)
2472 {
2473 	wpi_sc_t *sc = (wpi_sc_t *)arg;
2474 	ieee80211com_t	*ic = &sc->sc_ic;
2475 	int err;
2476 
2477 	if (!IEEE80211_ADDR_EQ(ic->ic_macaddr, macaddr)) {
2478 		IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr);
2479 		mutex_enter(&sc->sc_glock);
2480 		err = wpi_config(sc);
2481 		mutex_exit(&sc->sc_glock);
2482 		if (err != WPI_SUCCESS) {
2483 			cmn_err(CE_WARN,
2484 			    "wpi_m_unicst(): "
2485 			    "failed to configure device\n");
2486 			goto fail;
2487 		}
2488 	}
2489 	return (WPI_SUCCESS);
2490 fail:
2491 	return (err);
2492 }
2493 
2494 /*ARGSUSED*/
2495 static int
2496 wpi_m_multicst(void *arg, boolean_t add, const uint8_t *m)
2497 {
2498 	return (WPI_SUCCESS);
2499 }
2500 
2501 /*ARGSUSED*/
2502 static int
2503 wpi_m_promisc(void *arg, boolean_t on)
2504 {
2505 	return (WPI_SUCCESS);
2506 }
2507 
2508 static void
2509 wpi_thread(wpi_sc_t *sc)
2510 {
2511 	ieee80211com_t	*ic = &sc->sc_ic;
2512 	clock_t clk;
2513 	int times = 0, err, n = 0, timeout = 0;
2514 	uint32_t tmp;
2515 
2516 	mutex_enter(&sc->sc_mt_lock);
2517 	while (sc->sc_mf_thread_switch) {
2518 		tmp = WPI_READ(sc, WPI_GPIO_CTL);
2519 		if (tmp & WPI_GPIO_HW_RF_KILL) {
2520 			sc->sc_flags &= ~WPI_F_RADIO_OFF;
2521 		} else {
2522 			sc->sc_flags |= WPI_F_RADIO_OFF;
2523 		}
2524 		/*
2525 		 * If in SUSPEND or the RF is OFF, do nothing
2526 		 */
2527 		if ((sc->sc_flags & WPI_F_SUSPEND) ||
2528 		    (sc->sc_flags & WPI_F_RADIO_OFF)) {
2529 			mutex_exit(&sc->sc_mt_lock);
2530 			delay(drv_usectohz(100000));
2531 			mutex_enter(&sc->sc_mt_lock);
2532 			continue;
2533 		}
2534 
2535 		/*
2536 		 * recovery fatal error
2537 		 */
2538 		if (ic->ic_mach &&
2539 		    (sc->sc_flags & WPI_F_HW_ERR_RECOVER)) {
2540 
2541 			WPI_DBG((WPI_DEBUG_FW,
2542 			    "wpi_thread(): "
2543 			    "try to recover fatal hw error: %d\n", times++));
2544 
2545 			wpi_stop(sc);
2546 			mutex_exit(&sc->sc_mt_lock);
2547 
2548 			ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2549 			delay(drv_usectohz(2000000));
2550 
2551 			mutex_enter(&sc->sc_mt_lock);
2552 			err = wpi_init(sc);
2553 			if (err != WPI_SUCCESS) {
2554 				n++;
2555 				if (n < 3)
2556 					continue;
2557 			}
2558 			n = 0;
2559 			if (!err)
2560 				sc->sc_flags |= WPI_F_RUNNING;
2561 			sc->sc_flags &= ~WPI_F_HW_ERR_RECOVER;
2562 			mutex_exit(&sc->sc_mt_lock);
2563 			delay(drv_usectohz(2000000));
2564 			if (sc->sc_ostate != IEEE80211_S_INIT)
2565 				ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
2566 			mutex_enter(&sc->sc_mt_lock);
2567 		}
2568 
2569 		if (ic->ic_mach && (sc->sc_flags & WPI_F_LAZY_RESUME)) {
2570 			WPI_DBG((WPI_DEBUG_RESUME,
2571 			    "wpi_thread(): "
2572 			    "lazy resume\n"));
2573 			sc->sc_flags &= ~WPI_F_LAZY_RESUME;
2574 			mutex_exit(&sc->sc_mt_lock);
2575 			/*
2576 			 * NB: under WPA mode, this call hangs (door problem?)
2577 			 * when called in wpi_attach() and wpi_detach() while
2578 			 * system is in the procedure of CPR. To be safe, let
2579 			 * the thread do this.
2580 			 */
2581 			ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
2582 			mutex_enter(&sc->sc_mt_lock);
2583 		}
2584 
2585 		/*
2586 		 * scan next channel
2587 		 */
2588 		if (ic->ic_mach &&
2589 		    (sc->sc_flags & WPI_F_SCANNING) && sc->sc_scan_next) {
2590 
2591 			WPI_DBG((WPI_DEBUG_SCAN,
2592 			    "wpi_thread(): "
2593 			    "wait for probe response\n"));
2594 
2595 			sc->sc_scan_next--;
2596 			mutex_exit(&sc->sc_mt_lock);
2597 			delay(drv_usectohz(200000));
2598 			if (sc->sc_flags & WPI_F_SCANNING)
2599 				ieee80211_next_scan(ic);
2600 			mutex_enter(&sc->sc_mt_lock);
2601 		}
2602 
2603 		/*
2604 		 * rate ctl
2605 		 */
2606 		if (ic->ic_mach &&
2607 		    (sc->sc_flags & WPI_F_RATE_AUTO_CTL)) {
2608 			clk = ddi_get_lbolt();
2609 			if (clk > sc->sc_clk + drv_usectohz(500000)) {
2610 				wpi_amrr_timeout(sc);
2611 			}
2612 		}
2613 		mutex_exit(&sc->sc_mt_lock);
2614 		delay(drv_usectohz(100000));
2615 		mutex_enter(&sc->sc_mt_lock);
2616 		if (sc->sc_tx_timer) {
2617 			timeout++;
2618 			if (timeout == 10) {
2619 				sc->sc_tx_timer--;
2620 				if (sc->sc_tx_timer == 0) {
2621 					sc->sc_flags |= WPI_F_HW_ERR_RECOVER;
2622 					sc->sc_ostate = IEEE80211_S_RUN;
2623 					WPI_DBG((WPI_DEBUG_FW,
2624 					    "wpi_thread(): send fail\n"));
2625 				}
2626 				timeout = 0;
2627 			}
2628 		}
2629 	}
2630 	sc->sc_mf_thread = NULL;
2631 	cv_signal(&sc->sc_mt_cv);
2632 	mutex_exit(&sc->sc_mt_lock);
2633 }
2634 
2635 /*
2636  * Extract various information from EEPROM.
2637  */
2638 static void
2639 wpi_read_eeprom(wpi_sc_t *sc)
2640 {
2641 	ieee80211com_t *ic = &sc->sc_ic;
2642 	uint16_t val;
2643 	int i;
2644 
2645 	/* read MAC address */
2646 	val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 0);
2647 	ic->ic_macaddr[0] = val & 0xff;
2648 	ic->ic_macaddr[1] = val >> 8;
2649 	val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 1);
2650 	ic->ic_macaddr[2] = val & 0xff;
2651 	ic->ic_macaddr[3] = val >> 8;
2652 	val = wpi_read_prom_word(sc, WPI_EEPROM_MAC + 2);
2653 	ic->ic_macaddr[4] = val & 0xff;
2654 	ic->ic_macaddr[5] = val >> 8;
2655 
2656 	WPI_DBG((WPI_DEBUG_EEPROM,
2657 	    "mac:%2x:%2x:%2x:%2x:%2x:%2x\n",
2658 	    ic->ic_macaddr[0], ic->ic_macaddr[1],
2659 	    ic->ic_macaddr[2], ic->ic_macaddr[3],
2660 	    ic->ic_macaddr[4], ic->ic_macaddr[5]));
2661 	/* read power settings for 2.4GHz channels */
2662 	for (i = 0; i < 14; i++) {
2663 		sc->sc_pwr1[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR1 + i);
2664 		sc->sc_pwr2[i] = wpi_read_prom_word(sc, WPI_EEPROM_PWR2 + i);
2665 		WPI_DBG((WPI_DEBUG_EEPROM,
2666 		    "channel %d pwr1 0x%04x pwr2 0x%04x\n", i + 1,
2667 		    sc->sc_pwr1[i], sc->sc_pwr2[i]));
2668 	}
2669 }
2670 
2671 /*
2672  * Send a command to the firmware.
2673  */
2674 static int
2675 wpi_cmd(wpi_sc_t *sc, int code, const void *buf, int size, int async)
2676 {
2677 	wpi_tx_ring_t *ring = &sc->sc_cmdq;
2678 	wpi_tx_desc_t *desc;
2679 	wpi_tx_cmd_t *cmd;
2680 
2681 	ASSERT(size <= sizeof (cmd->data));
2682 	ASSERT(mutex_owned(&sc->sc_glock));
2683 
2684 	WPI_DBG((WPI_DEBUG_CMD, "wpi_cmd() # code[%d]", code));
2685 	desc = ring->data[ring->cur].desc;
2686 	cmd = ring->data[ring->cur].cmd;
2687 
2688 	cmd->code = (uint8_t)code;
2689 	cmd->flags = 0;
2690 	cmd->qid = ring->qid;
2691 	cmd->idx = ring->cur;
2692 	(void) memcpy(cmd->data, buf, size);
2693 
2694 	desc->flags = LE_32(WPI_PAD32(size) << 28 | 1 << 24);
2695 	desc->segs[0].addr = ring->data[ring->cur].paddr_cmd;
2696 	desc->segs[0].len  = 4 + size;
2697 
2698 	/* kick cmd ring */
2699 	ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT;
2700 	WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2701 
2702 	if (async)
2703 		return (WPI_SUCCESS);
2704 	else {
2705 		clock_t clk;
2706 		sc->sc_flags &= ~WPI_F_CMD_DONE;
2707 		clk = ddi_get_lbolt() + drv_usectohz(2000000);
2708 		while (!(sc->sc_flags & WPI_F_CMD_DONE)) {
2709 			if (cv_timedwait(&sc->sc_cmd_cv, &sc->sc_glock, clk)
2710 			    < 0)
2711 				break;
2712 		}
2713 		if (sc->sc_flags & WPI_F_CMD_DONE)
2714 			return (WPI_SUCCESS);
2715 		else
2716 			return (WPI_FAIL);
2717 	}
2718 }
2719 
2720 /*
2721  * Configure h/w multi-rate retries.
2722  */
2723 static int
2724 wpi_mrr_setup(wpi_sc_t *sc)
2725 {
2726 	wpi_mrr_setup_t mrr;
2727 	int i, err;
2728 
2729 	/* CCK rates (not used with 802.11a) */
2730 	for (i = WPI_CCK1; i <= WPI_CCK11; i++) {
2731 		mrr.rates[i].flags = 0;
2732 		mrr.rates[i].signal = wpi_ridx_to_signal[i];
2733 		/* fallback to the immediate lower CCK rate (if any) */
2734 		mrr.rates[i].next = (i == WPI_CCK1) ? WPI_CCK1 : i - 1;
2735 		/* try one time at this rate before falling back to "next" */
2736 		mrr.rates[i].ntries = 1;
2737 	}
2738 
2739 	/* OFDM rates (not used with 802.11b) */
2740 	for (i = WPI_OFDM6; i <= WPI_OFDM54; i++) {
2741 		mrr.rates[i].flags = 0;
2742 		mrr.rates[i].signal = wpi_ridx_to_signal[i];
2743 		/* fallback to the immediate lower OFDM rate (if any) */
2744 		mrr.rates[i].next = (i == WPI_OFDM6) ? WPI_OFDM6 : i - 1;
2745 		/* try one time at this rate before falling back to "next" */
2746 		mrr.rates[i].ntries = 1;
2747 	}
2748 
2749 	/* setup MRR for control frames */
2750 	mrr.which = LE_32(WPI_MRR_CTL);
2751 	err = wpi_cmd(sc, WPI_CMD_MRR_SETUP, &mrr, sizeof (mrr), 1);
2752 	if (err != WPI_SUCCESS) {
2753 		WPI_DBG((WPI_DEBUG_MRR,
2754 		    "could not setup MRR for control frames\n"));
2755 		return (err);
2756 	}
2757 
2758 	/* setup MRR for data frames */
2759 	mrr.which = LE_32(WPI_MRR_DATA);
2760 	err = wpi_cmd(sc, WPI_CMD_MRR_SETUP, &mrr, sizeof (mrr), 1);
2761 	if (err != WPI_SUCCESS) {
2762 		WPI_DBG((WPI_DEBUG_MRR,
2763 		    "could not setup MRR for data frames\n"));
2764 		return (err);
2765 	}
2766 
2767 	return (WPI_SUCCESS);
2768 }
2769 
2770 static void
2771 wpi_set_led(wpi_sc_t *sc, uint8_t which, uint8_t off, uint8_t on)
2772 {
2773 	wpi_cmd_led_t led;
2774 
2775 	led.which = which;
2776 	led.unit = LE_32(100000);	/* on/off in unit of 100ms */
2777 	led.off = off;
2778 	led.on = on;
2779 
2780 	(void) wpi_cmd(sc, WPI_CMD_SET_LED, &led, sizeof (led), 1);
2781 }
2782 
2783 static int
2784 wpi_auth(wpi_sc_t *sc)
2785 {
2786 	ieee80211com_t *ic = &sc->sc_ic;
2787 	ieee80211_node_t *in = ic->ic_bss;
2788 	wpi_node_t node;
2789 	int err;
2790 
2791 	/* update adapter's configuration */
2792 	IEEE80211_ADDR_COPY(sc->sc_config.bssid, in->in_bssid);
2793 	sc->sc_config.chan = ieee80211_chan2ieee(ic, in->in_chan);
2794 	if (ic->ic_curmode == IEEE80211_MODE_11B) {
2795 		sc->sc_config.cck_mask  = 0x03;
2796 		sc->sc_config.ofdm_mask = 0;
2797 	} else if ((in->in_chan != IEEE80211_CHAN_ANYC) &&
2798 	    (IEEE80211_IS_CHAN_5GHZ(in->in_chan))) {
2799 		sc->sc_config.cck_mask  = 0;
2800 		sc->sc_config.ofdm_mask = 0x15;
2801 	} else {	/* assume 802.11b/g */
2802 		sc->sc_config.cck_mask  = 0x0f;
2803 		sc->sc_config.ofdm_mask = 0xff;
2804 	}
2805 
2806 	WPI_DBG((WPI_DEBUG_80211, "config chan %d flags %x cck %x ofdm %x"
2807 	    " bssid:%02x:%02x:%02x:%02x:%02x:%2x\n",
2808 	    sc->sc_config.chan, sc->sc_config.flags,
2809 	    sc->sc_config.cck_mask, sc->sc_config.ofdm_mask,
2810 	    sc->sc_config.bssid[0], sc->sc_config.bssid[1],
2811 	    sc->sc_config.bssid[2], sc->sc_config.bssid[3],
2812 	    sc->sc_config.bssid[4], sc->sc_config.bssid[5]));
2813 	err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
2814 	    sizeof (wpi_config_t), 1);
2815 	if (err != WPI_SUCCESS) {
2816 		cmn_err(CE_WARN, "wpi_auth(): failed to configurate chan%d\n",
2817 		    sc->sc_config.chan);
2818 		return (err);
2819 	}
2820 
2821 	/* add default node */
2822 	(void) memset(&node, 0, sizeof (node));
2823 	IEEE80211_ADDR_COPY(node.bssid, in->in_bssid);
2824 	node.id = WPI_ID_BSS;
2825 	node.rate = wpi_plcp_signal(2);
2826 	err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 1);
2827 	if (err != WPI_SUCCESS) {
2828 		cmn_err(CE_WARN, "wpi_auth(): failed to add BSS node\n");
2829 		return (err);
2830 	}
2831 
2832 	err = wpi_mrr_setup(sc);
2833 	if (err != WPI_SUCCESS) {
2834 		cmn_err(CE_WARN, "wpi_auth(): failed to setup MRR\n");
2835 		return (err);
2836 	}
2837 
2838 	return (WPI_SUCCESS);
2839 }
2840 
2841 /*
2842  * Send a scan request to the firmware.
2843  */
2844 static int
2845 wpi_scan(wpi_sc_t *sc)
2846 {
2847 	ieee80211com_t *ic = &sc->sc_ic;
2848 	wpi_tx_ring_t *ring = &sc->sc_cmdq;
2849 	wpi_tx_desc_t *desc;
2850 	wpi_tx_data_t *data;
2851 	wpi_tx_cmd_t *cmd;
2852 	wpi_scan_hdr_t *hdr;
2853 	wpi_scan_chan_t *chan;
2854 	struct ieee80211_frame *wh;
2855 	ieee80211_node_t *in = ic->ic_bss;
2856 	uint8_t essid[IEEE80211_NWID_LEN+1];
2857 	struct ieee80211_rateset *rs;
2858 	enum ieee80211_phymode mode;
2859 	uint8_t *frm;
2860 	int i, pktlen, nrates;
2861 
2862 	/* previous scan not completed */
2863 	if (sc->sc_scan_pending) {
2864 		WPI_DBG((WPI_DEBUG_SCAN, "previous scan not completed\n"));
2865 		return (WPI_SUCCESS);
2866 	}
2867 
2868 	data = &ring->data[ring->cur];
2869 	desc = data->desc;
2870 	cmd = (wpi_tx_cmd_t *)data->dma_data.mem_va;
2871 
2872 	cmd->code = WPI_CMD_SCAN;
2873 	cmd->flags = 0;
2874 	cmd->qid = ring->qid;
2875 	cmd->idx = ring->cur;
2876 
2877 	hdr = (wpi_scan_hdr_t *)cmd->data;
2878 	(void) memset(hdr, 0, sizeof (wpi_scan_hdr_t));
2879 	hdr->first = 1;
2880 	hdr->nchan = 1;
2881 	hdr->len = hdr->nchan * sizeof (wpi_scan_chan_t);
2882 	hdr->quiet = LE_16(50);
2883 	hdr->threshold = LE_16(1);
2884 	hdr->filter = LE_32(5);
2885 	hdr->rate = wpi_plcp_signal(2);
2886 	hdr->id = WPI_ID_BROADCAST;
2887 	hdr->mask = LE_32(0xffffffff);
2888 	hdr->esslen = ic->ic_des_esslen;
2889 
2890 	if (ic->ic_des_esslen) {
2891 		bcopy(ic->ic_des_essid, essid, ic->ic_des_esslen);
2892 		essid[ic->ic_des_esslen] = '\0';
2893 		WPI_DBG((WPI_DEBUG_SCAN, "directed scan %s\n", essid));
2894 
2895 		bcopy(ic->ic_des_essid, hdr->essid, ic->ic_des_esslen);
2896 	} else {
2897 		bzero(hdr->essid, sizeof (hdr->essid));
2898 	}
2899 
2900 	/*
2901 	 * Build a probe request frame.  Most of the following code is a
2902 	 * copy & paste of what is done in net80211.  Unfortunately, the
2903 	 * functions to add IEs are static and thus can't be reused here.
2904 	 */
2905 	wh = (struct ieee80211_frame *)(hdr + 1);
2906 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
2907 	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
2908 	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2909 	(void) memset(wh->i_addr1, 0xff, 6);
2910 	IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_macaddr);
2911 	(void) memset(wh->i_addr3, 0xff, 6);
2912 	*(uint16_t *)&wh->i_dur[0] = 0;	/* filled by h/w */
2913 	*(uint16_t *)&wh->i_seq[0] = 0;	/* filled by h/w */
2914 
2915 	frm = (uint8_t *)(wh + 1);
2916 
2917 	/* add essid IE */
2918 	if (in->in_esslen) {
2919 		bcopy(in->in_essid, essid, in->in_esslen);
2920 		essid[in->in_esslen] = '\0';
2921 		WPI_DBG((WPI_DEBUG_SCAN, "probe with ESSID %s\n",
2922 		    essid));
2923 	}
2924 	*frm++ = IEEE80211_ELEMID_SSID;
2925 	*frm++ = in->in_esslen;
2926 	(void) memcpy(frm, in->in_essid, in->in_esslen);
2927 	frm += in->in_esslen;
2928 
2929 	mode = ieee80211_chan2mode(ic, ic->ic_curchan);
2930 	rs = &ic->ic_sup_rates[mode];
2931 
2932 	/* add supported rates IE */
2933 	*frm++ = IEEE80211_ELEMID_RATES;
2934 	nrates = rs->ir_nrates;
2935 	if (nrates > IEEE80211_RATE_SIZE)
2936 		nrates = IEEE80211_RATE_SIZE;
2937 	*frm++ = (uint8_t)nrates;
2938 	(void) memcpy(frm, rs->ir_rates, nrates);
2939 	frm += nrates;
2940 
2941 	/* add supported xrates IE */
2942 	if (rs->ir_nrates > IEEE80211_RATE_SIZE) {
2943 		nrates = rs->ir_nrates - IEEE80211_RATE_SIZE;
2944 		*frm++ = IEEE80211_ELEMID_XRATES;
2945 		*frm++ = (uint8_t)nrates;
2946 		(void) memcpy(frm, rs->ir_rates + IEEE80211_RATE_SIZE, nrates);
2947 		frm += nrates;
2948 	}
2949 
2950 	/* add optionnal IE (usually an RSN IE) */
2951 	if (ic->ic_opt_ie != NULL) {
2952 		(void) memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
2953 		frm += ic->ic_opt_ie_len;
2954 	}
2955 
2956 	/* setup length of probe request */
2957 	hdr->pbrlen = LE_16((uintptr_t)frm - (uintptr_t)wh);
2958 
2959 	/* align on a 4-byte boundary */
2960 	chan = (wpi_scan_chan_t *)frm;
2961 	for (i = 1; i <= hdr->nchan; i++, chan++) {
2962 		if (ic->ic_des_esslen) {
2963 			chan->flags = 0x3;
2964 		} else {
2965 			chan->flags = 0x1;
2966 		}
2967 		chan->chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
2968 		chan->magic = LE_16(0x62ab);
2969 		chan->active = LE_16(50);
2970 		chan->passive = LE_16(120);
2971 
2972 		frm += sizeof (wpi_scan_chan_t);
2973 	}
2974 
2975 	pktlen = (uintptr_t)frm - (uintptr_t)cmd;
2976 
2977 	desc->flags = LE_32(WPI_PAD32(pktlen) << 28 | 1 << 24);
2978 	desc->segs[0].addr = LE_32(data->dma_data.cookie.dmac_address);
2979 	desc->segs[0].len  = LE_32(pktlen);
2980 
2981 	WPI_DMA_SYNC(data->dma_data, DDI_DMA_SYNC_FORDEV);
2982 	WPI_DMA_SYNC(ring->dma_desc, DDI_DMA_SYNC_FORDEV);
2983 
2984 	/* kick cmd ring */
2985 	ring->cur = (ring->cur + 1) % WPI_CMD_RING_COUNT;
2986 	WPI_WRITE(sc, WPI_TX_WIDX, ring->qid << 8 | ring->cur);
2987 
2988 	sc->sc_scan_pending = 1;
2989 
2990 	return (WPI_SUCCESS);	/* will be notified async. of failure/success */
2991 }
2992 
2993 static int
2994 wpi_config(wpi_sc_t *sc)
2995 {
2996 	ieee80211com_t *ic = &sc->sc_ic;
2997 	wpi_txpower_t txpower;
2998 	wpi_power_t power;
2999 #ifdef WPI_BLUE_COEXISTENCE
3000 	wpi_bluetooth_t bluetooth;
3001 #endif
3002 	wpi_node_t node;
3003 	int err;
3004 
3005 	/* Intel's binary only daemon is a joke.. */
3006 
3007 	/* set Tx power for 2.4GHz channels (values read from EEPROM) */
3008 	(void) memset(&txpower, 0, sizeof (txpower));
3009 	(void) memcpy(txpower.pwr1, sc->sc_pwr1, 14 * sizeof (uint16_t));
3010 	(void) memcpy(txpower.pwr2, sc->sc_pwr2, 14 * sizeof (uint16_t));
3011 	err = wpi_cmd(sc, WPI_CMD_TXPOWER, &txpower, sizeof (txpower), 0);
3012 	if (err != WPI_SUCCESS) {
3013 		cmn_err(CE_WARN, "wpi_config(): failed to set txpower\n");
3014 		return (err);
3015 	}
3016 
3017 	/* set power mode */
3018 	(void) memset(&power, 0, sizeof (power));
3019 	power.flags = LE_32(0x8);
3020 	err = wpi_cmd(sc, WPI_CMD_SET_POWER_MODE, &power, sizeof (power), 0);
3021 	if (err != WPI_SUCCESS) {
3022 		cmn_err(CE_WARN, "wpi_config(): failed to set power mode\n");
3023 		return (err);
3024 	}
3025 #ifdef WPI_BLUE_COEXISTENCE
3026 	/* configure bluetooth coexistence */
3027 	(void) memset(&bluetooth, 0, sizeof (bluetooth));
3028 	bluetooth.flags = 3;
3029 	bluetooth.lead = 0xaa;
3030 	bluetooth.kill = 1;
3031 	err = wpi_cmd(sc, WPI_CMD_BLUETOOTH, &bluetooth,
3032 	    sizeof (bluetooth), 0);
3033 	if (err != WPI_SUCCESS) {
3034 		cmn_err(CE_WARN,
3035 		    "wpi_config(): "
3036 		    "failed to configurate bluetooth coexistence\n");
3037 		return (err);
3038 	}
3039 #endif
3040 	/* configure adapter */
3041 	(void) memset(&sc->sc_config, 0, sizeof (wpi_config_t));
3042 	IEEE80211_ADDR_COPY(sc->sc_config.myaddr, ic->ic_macaddr);
3043 	sc->sc_config.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3044 	sc->sc_config.flags = LE_32(WPI_CONFIG_TSF | WPI_CONFIG_AUTO |
3045 	    WPI_CONFIG_24GHZ);
3046 	sc->sc_config.filter = 0;
3047 	switch (ic->ic_opmode) {
3048 	case IEEE80211_M_STA:
3049 		sc->sc_config.mode = WPI_MODE_STA;
3050 		sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST);
3051 		break;
3052 	case IEEE80211_M_IBSS:
3053 	case IEEE80211_M_AHDEMO:
3054 		sc->sc_config.mode = WPI_MODE_IBSS;
3055 		break;
3056 	case IEEE80211_M_HOSTAP:
3057 		sc->sc_config.mode = WPI_MODE_HOSTAP;
3058 		break;
3059 	case IEEE80211_M_MONITOR:
3060 		sc->sc_config.mode = WPI_MODE_MONITOR;
3061 		sc->sc_config.filter |= LE_32(WPI_FILTER_MULTICAST |
3062 		    WPI_FILTER_CTL | WPI_FILTER_PROMISC);
3063 		break;
3064 	}
3065 	sc->sc_config.cck_mask  = 0x0f;	/* not yet negotiated */
3066 	sc->sc_config.ofdm_mask = 0xff;	/* not yet negotiated */
3067 	err = wpi_cmd(sc, WPI_CMD_CONFIGURE, &sc->sc_config,
3068 	    sizeof (wpi_config_t), 0);
3069 	if (err != WPI_SUCCESS) {
3070 		cmn_err(CE_WARN, "wpi_config(): "
3071 		    "failed to set configure command\n");
3072 		return (err);
3073 	}
3074 
3075 	/* add broadcast node */
3076 	(void) memset(&node, 0, sizeof (node));
3077 	(void) memset(node.bssid, 0xff, 6);
3078 	node.id = WPI_ID_BROADCAST;
3079 	node.rate = wpi_plcp_signal(2);
3080 	err = wpi_cmd(sc, WPI_CMD_ADD_NODE, &node, sizeof (node), 0);
3081 	if (err != WPI_SUCCESS) {
3082 		cmn_err(CE_WARN, "wpi_config(): "
3083 		    "failed to add broadcast node\n");
3084 		return (err);
3085 	}
3086 
3087 	return (WPI_SUCCESS);
3088 }
3089 
3090 static void
3091 wpi_stop_master(wpi_sc_t *sc)
3092 {
3093 	uint32_t tmp;
3094 	int ntries;
3095 
3096 	tmp = WPI_READ(sc, WPI_RESET);
3097 	WPI_WRITE(sc, WPI_RESET, tmp | WPI_STOP_MASTER);
3098 
3099 	tmp = WPI_READ(sc, WPI_GPIO_CTL);
3100 	if ((tmp & WPI_GPIO_PWR_STATUS) == WPI_GPIO_PWR_SLEEP)
3101 		return;	/* already asleep */
3102 
3103 	for (ntries = 0; ntries < 2000; ntries++) {
3104 		if (WPI_READ(sc, WPI_RESET) & WPI_MASTER_DISABLED)
3105 			break;
3106 		DELAY(1000);
3107 	}
3108 	if (ntries == 2000)
3109 		WPI_DBG((WPI_DEBUG_HW, "timeout waiting for master\n"));
3110 }
3111 
3112 static int
3113 wpi_power_up(wpi_sc_t *sc)
3114 {
3115 	uint32_t tmp;
3116 	int ntries;
3117 
3118 	wpi_mem_lock(sc);
3119 	tmp = wpi_mem_read(sc, WPI_MEM_POWER);
3120 	wpi_mem_write(sc, WPI_MEM_POWER, tmp & ~0x03000000);
3121 	wpi_mem_unlock(sc);
3122 
3123 	for (ntries = 0; ntries < 5000; ntries++) {
3124 		if (WPI_READ(sc, WPI_GPIO_STATUS) & WPI_POWERED)
3125 			break;
3126 		DELAY(10);
3127 	}
3128 	if (ntries == 5000) {
3129 		cmn_err(CE_WARN,
3130 		    "wpi_power_up(): timeout waiting for NIC to power up\n");
3131 		return (ETIMEDOUT);
3132 	}
3133 	return (WPI_SUCCESS);
3134 }
3135 
3136 static int
3137 wpi_reset(wpi_sc_t *sc)
3138 {
3139 	uint32_t tmp;
3140 	int ntries;
3141 
3142 	/* clear any pending interrupts */
3143 	WPI_WRITE(sc, WPI_INTR, 0xffffffff);
3144 
3145 	tmp = WPI_READ(sc, WPI_PLL_CTL);
3146 	WPI_WRITE(sc, WPI_PLL_CTL, tmp | WPI_PLL_INIT);
3147 
3148 	tmp = WPI_READ(sc, WPI_CHICKEN);
3149 	WPI_WRITE(sc, WPI_CHICKEN, tmp | WPI_CHICKEN_RXNOLOS);
3150 
3151 	tmp = WPI_READ(sc, WPI_GPIO_CTL);
3152 	WPI_WRITE(sc, WPI_GPIO_CTL, tmp | WPI_GPIO_INIT);
3153 
3154 	/* wait for clock stabilization */
3155 	for (ntries = 0; ntries < 1000; ntries++) {
3156 		if (WPI_READ(sc, WPI_GPIO_CTL) & WPI_GPIO_CLOCK)
3157 			break;
3158 		DELAY(10);
3159 	}
3160 	if (ntries == 1000) {
3161 		cmn_err(CE_WARN,
3162 		    "wpi_reset(): timeout waiting for clock stabilization\n");
3163 		return (ETIMEDOUT);
3164 	}
3165 
3166 	/* initialize EEPROM */
3167 	tmp = WPI_READ(sc, WPI_EEPROM_STATUS);
3168 	if ((tmp & WPI_EEPROM_VERSION) == 0) {
3169 		cmn_err(CE_WARN, "wpi_reset(): EEPROM not found\n");
3170 		return (EIO);
3171 	}
3172 	WPI_WRITE(sc, WPI_EEPROM_STATUS, tmp & ~WPI_EEPROM_LOCKED);
3173 
3174 	return (WPI_SUCCESS);
3175 }
3176 
3177 static void
3178 wpi_hw_config(wpi_sc_t *sc)
3179 {
3180 	uint16_t val;
3181 	uint32_t hw;
3182 
3183 	/* voodoo from the Linux "driver".. */
3184 	hw = WPI_READ(sc, WPI_HWCONFIG);
3185 
3186 	if ((sc->sc_rev & 0xc0) == 0x40)
3187 		hw |= WPI_HW_ALM_MB;
3188 	else if (!(sc->sc_rev & 0x80))
3189 		hw |= WPI_HW_ALM_MM;
3190 
3191 	val = wpi_read_prom_word(sc, WPI_EEPROM_CAPABILITIES);
3192 	if ((val & 0xff) == 0x80)
3193 		hw |= WPI_HW_SKU_MRC;
3194 
3195 	val = wpi_read_prom_word(sc, WPI_EEPROM_REVISION);
3196 	hw &= ~WPI_HW_REV_D;
3197 	if ((val & 0xf0) == 0xd0)
3198 		hw |= WPI_HW_REV_D;
3199 
3200 	val = wpi_read_prom_word(sc, WPI_EEPROM_TYPE);
3201 	if ((val & 0xff) > 1)
3202 		hw |= WPI_HW_TYPE_B;
3203 
3204 	WPI_DBG((WPI_DEBUG_HW, "setting h/w config %x\n", hw));
3205 	WPI_WRITE(sc, WPI_HWCONFIG, hw);
3206 }
3207 
3208 static int
3209 wpi_init(wpi_sc_t *sc)
3210 {
3211 	uint32_t tmp;
3212 	int qid, ntries, err;
3213 	clock_t clk;
3214 
3215 	mutex_enter(&sc->sc_glock);
3216 	sc->sc_flags &= ~WPI_F_FW_INIT;
3217 
3218 	(void) wpi_reset(sc);
3219 
3220 	wpi_mem_lock(sc);
3221 	wpi_mem_write(sc, WPI_MEM_CLOCK1, 0xa00);
3222 	DELAY(20);
3223 	tmp = wpi_mem_read(sc, WPI_MEM_PCIDEV);
3224 	wpi_mem_write(sc, WPI_MEM_PCIDEV, tmp | 0x800);
3225 	wpi_mem_unlock(sc);
3226 
3227 	(void) wpi_power_up(sc);
3228 	wpi_hw_config(sc);
3229 
3230 	tmp = WPI_READ(sc, WPI_GPIO_CTL);
3231 	if (!(tmp & WPI_GPIO_HW_RF_KILL)) {
3232 		cmn_err(CE_WARN, "wpi_init(): Radio transmitter is off\n");
3233 		goto fail1;
3234 	}
3235 
3236 	/* init Rx ring */
3237 	wpi_mem_lock(sc);
3238 	WPI_WRITE(sc, WPI_RX_BASE, sc->sc_rxq.dma_desc.cookie.dmac_address);
3239 	WPI_WRITE(sc, WPI_RX_RIDX_PTR,
3240 	    (uint32_t)(sc->sc_dma_sh.cookie.dmac_address +
3241 	    offsetof(wpi_shared_t, next)));
3242 	WPI_WRITE(sc, WPI_RX_WIDX, (WPI_RX_RING_COUNT - 1) & (~7));
3243 	WPI_WRITE(sc, WPI_RX_CONFIG, 0xa9601010);
3244 	wpi_mem_unlock(sc);
3245 
3246 	/* init Tx rings */
3247 	wpi_mem_lock(sc);
3248 	wpi_mem_write(sc, WPI_MEM_MODE, 2);	/* bypass mode */
3249 	wpi_mem_write(sc, WPI_MEM_RA, 1);	/* enable RA0 */
3250 	wpi_mem_write(sc, WPI_MEM_TXCFG, 0x3f);	/* enable all 6 Tx rings */
3251 	wpi_mem_write(sc, WPI_MEM_BYPASS1, 0x10000);
3252 	wpi_mem_write(sc, WPI_MEM_BYPASS2, 0x30002);
3253 	wpi_mem_write(sc, WPI_MEM_MAGIC4, 4);
3254 	wpi_mem_write(sc, WPI_MEM_MAGIC5, 5);
3255 
3256 	WPI_WRITE(sc, WPI_TX_BASE_PTR, sc->sc_dma_sh.cookie.dmac_address);
3257 	WPI_WRITE(sc, WPI_MSG_CONFIG, 0xffff05a5);
3258 
3259 	for (qid = 0; qid < 6; qid++) {
3260 		WPI_WRITE(sc, WPI_TX_CTL(qid), 0);
3261 		WPI_WRITE(sc, WPI_TX_BASE(qid), 0);
3262 		WPI_WRITE(sc, WPI_TX_CONFIG(qid), 0x80200008);
3263 	}
3264 	wpi_mem_unlock(sc);
3265 
3266 	/* clear "radio off" and "disable command" bits (reversed logic) */
3267 	WPI_WRITE(sc, WPI_UCODE_CLR, WPI_RADIO_OFF);
3268 	WPI_WRITE(sc, WPI_UCODE_CLR, WPI_DISABLE_CMD);
3269 
3270 	/* clear any pending interrupts */
3271 	WPI_WRITE(sc, WPI_INTR, 0xffffffff);
3272 
3273 	/* enable interrupts */
3274 	WPI_WRITE(sc, WPI_MASK, WPI_INTR_MASK);
3275 
3276 	/* load firmware boot code into NIC */
3277 	err = wpi_load_microcode(sc);
3278 	if (err != WPI_SUCCESS) {
3279 		cmn_err(CE_WARN, "wpi_init(): failed to load microcode\n");
3280 		goto fail1;
3281 	}
3282 
3283 	/* load firmware .text segment into NIC */
3284 	err = wpi_load_firmware(sc, WPI_FW_TEXT);
3285 	if (err != WPI_SUCCESS) {
3286 		cmn_err(CE_WARN, "wpi_init(): "
3287 		    "failed to load firmware(text)\n");
3288 		goto fail1;
3289 	}
3290 
3291 	/* load firmware .data segment into NIC */
3292 	err = wpi_load_firmware(sc, WPI_FW_DATA);
3293 	if (err != WPI_SUCCESS) {
3294 		cmn_err(CE_WARN, "wpi_init(): "
3295 		    "failed to load firmware(data)\n");
3296 		goto fail1;
3297 	}
3298 
3299 	/* now press "execute" ;-) */
3300 	tmp = WPI_READ(sc, WPI_RESET);
3301 	tmp &= ~(WPI_MASTER_DISABLED | WPI_STOP_MASTER | WPI_NEVO_RESET);
3302 	WPI_WRITE(sc, WPI_RESET, tmp);
3303 
3304 	/* ..and wait at most one second for adapter to initialize */
3305 	clk = ddi_get_lbolt() + drv_usectohz(2000000);
3306 	while (!(sc->sc_flags & WPI_F_FW_INIT)) {
3307 		if (cv_timedwait(&sc->sc_fw_cv, &sc->sc_glock, clk) < 0)
3308 			break;
3309 	}
3310 	if (!(sc->sc_flags & WPI_F_FW_INIT)) {
3311 		cmn_err(CE_WARN,
3312 		    "wpi_init(): timeout waiting for firmware init\n");
3313 		goto fail1;
3314 	}
3315 
3316 	/* wait for thermal sensors to calibrate */
3317 	for (ntries = 0; ntries < 1000; ntries++) {
3318 		if (WPI_READ(sc, WPI_TEMPERATURE) != 0)
3319 			break;
3320 		DELAY(10);
3321 	}
3322 
3323 	if (ntries == 1000) {
3324 		WPI_DBG((WPI_DEBUG_HW,
3325 		    "wpi_init(): timeout waiting for thermal sensors "
3326 		    "calibration\n"));
3327 	}
3328 
3329 	WPI_DBG((WPI_DEBUG_HW, "temperature %d\n",
3330 	    (int)WPI_READ(sc, WPI_TEMPERATURE)));
3331 
3332 	err = wpi_config(sc);
3333 	if (err) {
3334 		cmn_err(CE_WARN, "wpi_init(): failed to configure device\n");
3335 		goto fail1;
3336 	}
3337 
3338 	mutex_exit(&sc->sc_glock);
3339 	return (WPI_SUCCESS);
3340 
3341 fail1:
3342 	err = WPI_FAIL;
3343 	mutex_exit(&sc->sc_glock);
3344 	return (err);
3345 }
3346 
3347 /*
3348  * quiesce(9E) entry point.
3349  * This function is called when the system is single-threaded at high
3350  * PIL with preemption disabled. Therefore, this function must not be
3351  * blocked.
3352  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
3353  * DDI_FAILURE indicates an error condition and should almost never happen.
3354  */
3355 static int
3356 wpi_quiesce(dev_info_t *dip)
3357 {
3358 	wpi_sc_t *sc;
3359 
3360 	sc = ddi_get_soft_state(wpi_soft_state_p, ddi_get_instance(dip));
3361 	if (sc == NULL)
3362 		return (DDI_FAILURE);
3363 
3364 #ifdef DEBUG
3365 	/* by pass any messages, if it's quiesce */
3366 	wpi_dbg_flags = 0;
3367 #endif
3368 
3369 	/*
3370 	 * No more blocking is allowed while we are in the
3371 	 * quiesce(9E) entry point.
3372 	 */
3373 	sc->sc_flags |= WPI_F_QUIESCED;
3374 
3375 	/*
3376 	 * Disable and mask all interrupts.
3377 	 */
3378 	wpi_stop(sc);
3379 	return (DDI_SUCCESS);
3380 }
3381 
3382 static void
3383 wpi_stop(wpi_sc_t *sc)
3384 {
3385 	uint32_t tmp;
3386 	int ac;
3387 
3388 	/* no mutex operation, if it's quiesced */
3389 	if (!(sc->sc_flags & WPI_F_QUIESCED))
3390 		mutex_enter(&sc->sc_glock);
3391 
3392 	/* disable interrupts */
3393 	WPI_WRITE(sc, WPI_MASK, 0);
3394 	WPI_WRITE(sc, WPI_INTR, WPI_INTR_MASK);
3395 	WPI_WRITE(sc, WPI_INTR_STATUS, 0xff);
3396 	WPI_WRITE(sc, WPI_INTR_STATUS, 0x00070000);
3397 
3398 	wpi_mem_lock(sc);
3399 	wpi_mem_write(sc, WPI_MEM_MODE, 0);
3400 	wpi_mem_unlock(sc);
3401 
3402 	/* reset all Tx rings */
3403 	for (ac = 0; ac < 4; ac++)
3404 		wpi_reset_tx_ring(sc, &sc->sc_txq[ac]);
3405 	wpi_reset_tx_ring(sc, &sc->sc_cmdq);
3406 	wpi_reset_tx_ring(sc, &sc->sc_svcq);
3407 
3408 	/* reset Rx ring */
3409 	wpi_reset_rx_ring(sc);
3410 
3411 	wpi_mem_lock(sc);
3412 	wpi_mem_write(sc, WPI_MEM_CLOCK2, 0x200);
3413 	wpi_mem_unlock(sc);
3414 
3415 	DELAY(5);
3416 
3417 	wpi_stop_master(sc);
3418 
3419 	sc->sc_tx_timer = 0;
3420 	sc->sc_flags &= ~WPI_F_SCANNING;
3421 	sc->sc_scan_pending = 0;
3422 	sc->sc_scan_next = 0;
3423 
3424 	tmp = WPI_READ(sc, WPI_RESET);
3425 	WPI_WRITE(sc, WPI_RESET, tmp | WPI_SW_RESET);
3426 
3427 	/* no mutex operation, if it's quiesced */
3428 	if (!(sc->sc_flags & WPI_F_QUIESCED))
3429 		mutex_exit(&sc->sc_glock);
3430 }
3431 
3432 /*
3433  * Naive implementation of the Adaptive Multi Rate Retry algorithm:
3434  * "IEEE 802.11 Rate Adaptation: A Practical Approach"
3435  * Mathieu Lacage, Hossein Manshaei, Thierry Turletti
3436  * INRIA Sophia - Projet Planete
3437  * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
3438  */
3439 #define	is_success(amrr)	\
3440 	((amrr)->retrycnt < (amrr)->txcnt / 10)
3441 #define	is_failure(amrr)	\
3442 	((amrr)->retrycnt > (amrr)->txcnt / 3)
3443 #define	is_enough(amrr)		\
3444 	((amrr)->txcnt > 100)
3445 #define	is_min_rate(in)		\
3446 	((in)->in_txrate == 0)
3447 #define	is_max_rate(in)		\
3448 	((in)->in_txrate == (in)->in_rates.ir_nrates - 1)
3449 #define	increase_rate(in)	\
3450 	((in)->in_txrate++)
3451 #define	decrease_rate(in)	\
3452 	((in)->in_txrate--)
3453 #define	reset_cnt(amrr)		\
3454 	{ (amrr)->txcnt = (amrr)->retrycnt = 0; }
3455 
3456 #define	WPI_AMRR_MIN_SUCCESS_THRESHOLD	 1
3457 #define	WPI_AMRR_MAX_SUCCESS_THRESHOLD	15
3458 
3459 static void
3460 wpi_amrr_init(wpi_amrr_t *amrr)
3461 {
3462 	amrr->success = 0;
3463 	amrr->recovery = 0;
3464 	amrr->txcnt = amrr->retrycnt = 0;
3465 	amrr->success_threshold = WPI_AMRR_MIN_SUCCESS_THRESHOLD;
3466 }
3467 
3468 static void
3469 wpi_amrr_timeout(wpi_sc_t *sc)
3470 {
3471 	ieee80211com_t *ic = &sc->sc_ic;
3472 
3473 	WPI_DBG((WPI_DEBUG_RATECTL, "wpi_amrr_timeout() enter\n"));
3474 	if (ic->ic_opmode == IEEE80211_M_STA)
3475 		wpi_amrr_ratectl(NULL, ic->ic_bss);
3476 	else
3477 		ieee80211_iterate_nodes(&ic->ic_sta, wpi_amrr_ratectl, NULL);
3478 	sc->sc_clk = ddi_get_lbolt();
3479 }
3480 
3481 /* ARGSUSED */
3482 static void
3483 wpi_amrr_ratectl(void *arg, ieee80211_node_t *in)
3484 {
3485 	wpi_amrr_t *amrr = (wpi_amrr_t *)in;
3486 	int need_change = 0;
3487 
3488 	if (is_success(amrr) && is_enough(amrr)) {
3489 		amrr->success++;
3490 		if (amrr->success >= amrr->success_threshold &&
3491 		    !is_max_rate(in)) {
3492 			amrr->recovery = 1;
3493 			amrr->success = 0;
3494 			increase_rate(in);
3495 			WPI_DBG((WPI_DEBUG_RATECTL,
3496 			    "AMRR increasing rate %d (txcnt=%d retrycnt=%d)\n",
3497 			    in->in_txrate, amrr->txcnt, amrr->retrycnt));
3498 			need_change = 1;
3499 		} else {
3500 			amrr->recovery = 0;
3501 		}
3502 	} else if (is_failure(amrr)) {
3503 		amrr->success = 0;
3504 		if (!is_min_rate(in)) {
3505 			if (amrr->recovery) {
3506 				amrr->success_threshold++;
3507 				if (amrr->success_threshold >
3508 				    WPI_AMRR_MAX_SUCCESS_THRESHOLD)
3509 					amrr->success_threshold =
3510 					    WPI_AMRR_MAX_SUCCESS_THRESHOLD;
3511 			} else {
3512 				amrr->success_threshold =
3513 				    WPI_AMRR_MIN_SUCCESS_THRESHOLD;
3514 			}
3515 			decrease_rate(in);
3516 			WPI_DBG((WPI_DEBUG_RATECTL,
3517 			    "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)\n",
3518 			    in->in_txrate, amrr->txcnt, amrr->retrycnt));
3519 			need_change = 1;
3520 		}
3521 		amrr->recovery = 0;	/* paper is incorrect */
3522 	}
3523 
3524 	if (is_enough(amrr) || need_change)
3525 		reset_cnt(amrr);
3526 }
3527