xref: /illumos-gate/usr/src/uts/common/io/ath/ath_main.c (revision 8a8d276f)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer,
15  * without modification.
16  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17  * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
18  * redistribution must be conditioned upon including a substantially
19  * similar Disclaimer requirement for further binary redistribution.
20  * 3. Neither the names of the above-listed copyright holders nor the names
21  * of any contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * NO WARRANTY
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
28  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
30  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGES.
36  *
37  */
38 
39 #pragma ident	"%Z%%M%	%I%	%E% SMI"
40 
41 /*
42  * Driver for the Atheros Wireless LAN controller.
43  *
44  * The Atheros driver calls into net80211 module for IEEE80211 protocol
45  * management functionalities. The driver includes a LLD(Low Level Driver)
46  * part to implement H/W related operations.
47  * The following is the high level structure of ath driver.
48  * (The arrows between modules indicate function call direction.)
49  *
50  *
51  *                                                  |
52  *                                                  | GLD thread
53  *                                                  V
54  *         ==================  =========================================
55  *         |                |  |[1]                                    |
56  *         |                |  |  GLDv3 Callback functions registered  |
57  *         |   Net80211     |  =========================       by      |
58  *         |    module      |          |               |     driver    |
59  *         |                |          V               |               |
60  *         |                |========================  |               |
61  *         |   Functions exported by net80211       |  |               |
62  *         |                                        |  |               |
63  *         ==========================================  =================
64  *                         |                                  |
65  *                         V                                  |
66  *         +----------------------------------+               |
67  *         |[2]                               |               |
68  *         |    Net80211 Callback functions   |               |
69  *         |      registered by LLD           |               |
70  *         +----------------------------------+               |
71  *                         |                                  |
72  *                         V                                  v
73  *         +-----------------------------------------------------------+
74  *         |[3]                                                        |
75  *         |                LLD Internal functions                     |
76  *         |                                                           |
77  *         +-----------------------------------------------------------+
78  *                                    ^
79  *                                    | Software interrupt thread
80  *                                    |
81  *
82  * The short description of each module is as below:
83  *      Module 1: GLD callback functions, which are intercepting the calls from
84  *                GLD to LLD.
85  *      Module 2: Net80211 callback functions registered by LLD, which
86  *                calls into LLD for H/W related functions needed by net80211.
87  *      Module 3: LLD Internal functions, which are responsible for allocing
88  *                descriptor/buffer, handling interrupt and other H/W
89  *                operations.
90  *
91  * All functions are running in 3 types of thread:
92  * 1. GLD callbacks threads, such as ioctl, intr, etc.
93  * 2. Clock interruptt thread which is responsible for scan, rate control and
94  *    calibration.
95  * 3. Software Interrupt thread originated in LLD.
96  *
97  * The lock strategy is as below:
98  * There have 4 queues for tx, each queue has one asc_txqlock[i] to
99  *      prevent conflicts access to queue resource from different thread.
100  *
101  * All the transmit buffers are contained in asc_txbuf which are
102  *      protected by asc_txbuflock.
103  *
104  * Each receive buffers are contained in asc_rxbuf which are protected
105  *      by asc_rxbuflock.
106  *
107  * In ath struct, asc_genlock is a general lock, protecting most other
108  *      operational data in ath_softc struct and HAL accesses.
109  *      It is acquired by the interupt handler and most "mode-ctrl" routines.
110  *
111  * Any of the locks can be acquired singly, but where multiple
112  * locks are acquired, they *must* be in the order:
113  *    asc_genlock >> asc_txqlock[i] >> asc_txbuflock >> asc_rxbuflock
114  */
115 
116 #include <sys/param.h>
117 #include <sys/types.h>
118 #include <sys/signal.h>
119 #include <sys/stream.h>
120 #include <sys/termio.h>
121 #include <sys/errno.h>
122 #include <sys/file.h>
123 #include <sys/cmn_err.h>
124 #include <sys/stropts.h>
125 #include <sys/strsubr.h>
126 #include <sys/strtty.h>
127 #include <sys/kbio.h>
128 #include <sys/cred.h>
129 #include <sys/stat.h>
130 #include <sys/consdev.h>
131 #include <sys/kmem.h>
132 #include <sys/modctl.h>
133 #include <sys/ddi.h>
134 #include <sys/sunddi.h>
135 #include <sys/pci.h>
136 #include <sys/errno.h>
137 #include <sys/mac.h>
138 #include <sys/dlpi.h>
139 #include <sys/ethernet.h>
140 #include <sys/list.h>
141 #include <sys/byteorder.h>
142 #include <sys/strsun.h>
143 #include <sys/policy.h>
144 #include <inet/common.h>
145 #include <inet/nd.h>
146 #include <inet/mi.h>
147 #include <inet/wifi_ioctl.h>
148 #include <sys/mac_wifi.h>
149 #include "ath_hal.h"
150 #include "ath_impl.h"
151 #include "ath_aux.h"
152 #include "ath_rate.h"
153 
154 #define	ATH_MAX_RSSI	63	/* max rssi */
155 
156 extern void ath_halfix_init(void);
157 extern void ath_halfix_finit(void);
158 extern int32_t ath_getset(ath_t *asc, mblk_t *mp, uint32_t cmd);
159 
160 /*
161  * PIO access attributes for registers
162  */
163 static ddi_device_acc_attr_t ath_reg_accattr = {
164 	DDI_DEVICE_ATTR_V0,
165 	DDI_STRUCTURE_LE_ACC,
166 	DDI_STRICTORDER_ACC
167 };
168 
169 /*
170  * DMA access attributes for descriptors: NOT to be byte swapped.
171  */
172 static ddi_device_acc_attr_t ath_desc_accattr = {
173 	DDI_DEVICE_ATTR_V0,
174 	DDI_STRUCTURE_LE_ACC,
175 	DDI_STRICTORDER_ACC
176 };
177 
178 /*
179  * Describes the chip's DMA engine
180  */
181 static ddi_dma_attr_t dma_attr = {
182 	DMA_ATTR_V0,			/* dma_attr version */
183 	0x0000000000000000ull,		/* dma_attr_addr_lo */
184 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_addr_hi */
185 	0x00000000FFFFFFFFull,		/* dma_attr_count_max */
186 	0x0000000000000001ull,		/* dma_attr_align */
187 	0x00000FFF,			/* dma_attr_burstsizes */
188 	0x00000001,			/* dma_attr_minxfer */
189 	0x000000000000FFFFull,		/* dma_attr_maxxfer */
190 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_seg */
191 	1,				/* dma_attr_sgllen */
192 	0x00000001,			/* dma_attr_granular */
193 	0				/* dma_attr_flags */
194 };
195 
196 static kmutex_t ath_loglock;
197 static void *ath_soft_state_p = NULL;
198 static int ath_dwelltime = 150;		/* scan interval, ms */
199 
200 static int	ath_m_stat(void *,  uint_t, uint64_t *);
201 static int	ath_m_start(void *);
202 static void	ath_m_stop(void *);
203 static int	ath_m_promisc(void *, boolean_t);
204 static int	ath_m_multicst(void *, boolean_t, const uint8_t *);
205 static int	ath_m_unicst(void *, const uint8_t *);
206 static mblk_t	*ath_m_tx(void *, mblk_t *);
207 static void	ath_m_ioctl(void *, queue_t *, mblk_t *);
208 static mac_callbacks_t ath_m_callbacks = {
209 	MC_IOCTL,
210 	ath_m_stat,
211 	ath_m_start,
212 	ath_m_stop,
213 	ath_m_promisc,
214 	ath_m_multicst,
215 	ath_m_unicst,
216 	ath_m_tx,
217 	NULL,		/* mc_resources; */
218 	ath_m_ioctl,
219 	NULL		/* mc_getcapab */
220 };
221 
222 /*
223  * Available debug flags:
224  * ATH_DBG_INIT, ATH_DBG_GLD, ATH_DBG_HAL, ATH_DBG_INT, ATH_DBG_ATTACH,
225  * ATH_DBG_DETACH, ATH_DBG_AUX, ATH_DBG_WIFICFG, ATH_DBG_OSDEP
226  */
227 uint32_t ath_dbg_flags = 0;
228 
229 /*
230  * Exception/warning cases not leading to panic.
231  */
232 void
233 ath_problem(const int8_t *fmt, ...)
234 {
235 	va_list args;
236 
237 	mutex_enter(&ath_loglock);
238 
239 	va_start(args, fmt);
240 	vcmn_err(CE_WARN, fmt, args);
241 	va_end(args);
242 
243 	mutex_exit(&ath_loglock);
244 }
245 
246 /*
247  * Normal log information independent of debug.
248  */
249 void
250 ath_log(const int8_t *fmt, ...)
251 {
252 	va_list args;
253 
254 	mutex_enter(&ath_loglock);
255 
256 	va_start(args, fmt);
257 	vcmn_err(CE_CONT, fmt, args);
258 	va_end(args);
259 
260 	mutex_exit(&ath_loglock);
261 }
262 
263 void
264 ath_dbg(uint32_t dbg_flags, const int8_t *fmt, ...)
265 {
266 	va_list args;
267 
268 	if (dbg_flags & ath_dbg_flags) {
269 		mutex_enter(&ath_loglock);
270 		va_start(args, fmt);
271 		vcmn_err(CE_CONT, fmt, args);
272 		va_end(args);
273 		mutex_exit(&ath_loglock);
274 	}
275 }
276 
277 void
278 ath_setup_desc(ath_t *asc, struct ath_buf *bf)
279 {
280 	struct ath_desc *ds;
281 
282 	ds = bf->bf_desc;
283 	ds->ds_link = bf->bf_daddr;
284 	ds->ds_data = bf->bf_dma.cookie.dmac_address;
285 	ds->ds_vdata = bf->bf_dma.mem_va;
286 	ATH_HAL_SETUPRXDESC(asc->asc_ah, ds,
287 	    bf->bf_dma.alength,		/* buffer size */
288 	    0);
289 
290 	if (asc->asc_rxlink != NULL)
291 		*asc->asc_rxlink = bf->bf_daddr;
292 	asc->asc_rxlink = &ds->ds_link;
293 }
294 
295 
296 /*
297  * Allocate an area of memory and a DMA handle for accessing it
298  */
299 static int
300 ath_alloc_dma_mem(dev_info_t *devinfo, size_t memsize,
301 	ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
302 	uint_t bind_flags, dma_area_t *dma_p)
303 {
304 	int err;
305 
306 	/*
307 	 * Allocate handle
308 	 */
309 	err = ddi_dma_alloc_handle(devinfo, &dma_attr,
310 		DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
311 	if (err != DDI_SUCCESS)
312 		return (DDI_FAILURE);
313 
314 	/*
315 	 * Allocate memory
316 	 */
317 	err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
318 	    alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
319 	    &dma_p->alength, &dma_p->acc_hdl);
320 	if (err != DDI_SUCCESS)
321 		return (DDI_FAILURE);
322 
323 	/*
324 	 * Bind the two together
325 	 */
326 	err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
327 		dma_p->mem_va, dma_p->alength, bind_flags,
328 		DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
329 	if (err != DDI_DMA_MAPPED)
330 		return (DDI_FAILURE);
331 
332 	dma_p->nslots = ~0U;
333 	dma_p->size = ~0U;
334 	dma_p->token = ~0U;
335 	dma_p->offset = 0;
336 	return (DDI_SUCCESS);
337 }
338 
339 /*
340  * Free one allocated area of DMAable memory
341  */
342 static void
343 ath_free_dma_mem(dma_area_t *dma_p)
344 {
345 	if (dma_p->dma_hdl != NULL) {
346 		(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
347 		if (dma_p->acc_hdl != NULL) {
348 			ddi_dma_mem_free(&dma_p->acc_hdl);
349 			dma_p->acc_hdl = NULL;
350 		}
351 		ddi_dma_free_handle(&dma_p->dma_hdl);
352 		dma_p->ncookies = 0;
353 		dma_p->dma_hdl = NULL;
354 	}
355 }
356 
357 
358 static int
359 ath_desc_alloc(dev_info_t *devinfo, ath_t *asc)
360 {
361 	int i, err;
362 	size_t size;
363 	struct ath_desc *ds;
364 	struct ath_buf *bf;
365 
366 	size = sizeof (struct ath_desc) * (ATH_TXBUF + ATH_RXBUF);
367 
368 	err = ath_alloc_dma_mem(devinfo, size, &ath_desc_accattr,
369 	    DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
370 	    &asc->asc_desc_dma);
371 
372 	/* virtual address of the first descriptor */
373 	asc->asc_desc = (struct ath_desc *)asc->asc_desc_dma.mem_va;
374 
375 	ds = asc->asc_desc;
376 	ATH_DEBUG((ATH_DBG_INIT, "ath: ath_desc_alloc(): DMA map: "
377 	    "%p (%d) -> %p\n",
378 	    asc->asc_desc, asc->asc_desc_dma.alength,
379 	    asc->asc_desc_dma.cookie.dmac_address));
380 
381 	/* allocate data structures to describe TX/RX DMA buffers */
382 	asc->asc_vbuflen = sizeof (struct ath_buf) * (ATH_TXBUF + ATH_RXBUF);
383 	bf = (struct ath_buf *)kmem_zalloc(asc->asc_vbuflen, KM_SLEEP);
384 	asc->asc_vbufptr = bf;
385 
386 	/* DMA buffer size for each TX/RX packet */
387 	asc->asc_dmabuf_size = roundup(1000 + sizeof (struct ieee80211_frame) +
388 	    IEEE80211_MTU + IEEE80211_CRC_LEN +
389 	    (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
390 	    IEEE80211_WEP_CRCLEN), asc->asc_cachelsz);
391 
392 	/* create RX buffer list and allocate DMA memory */
393 	list_create(&asc->asc_rxbuf_list, sizeof (struct ath_buf),
394 	    offsetof(struct ath_buf, bf_node));
395 	for (i = 0; i < ATH_RXBUF; i++, bf++, ds++) {
396 		bf->bf_desc = ds;
397 		bf->bf_daddr = asc->asc_desc_dma.cookie.dmac_address +
398 		    ((caddr_t)ds - (caddr_t)asc->asc_desc);
399 		list_insert_tail(&asc->asc_rxbuf_list, bf);
400 
401 		/* alloc DMA memory */
402 		err = ath_alloc_dma_mem(devinfo, asc->asc_dmabuf_size,
403 		    &ath_desc_accattr,
404 		    DDI_DMA_STREAMING, DDI_DMA_READ | DDI_DMA_STREAMING,
405 		    &bf->bf_dma);
406 		if (err != DDI_SUCCESS)
407 			return (err);
408 	}
409 
410 	/* create TX buffer list and allocate DMA memory */
411 	list_create(&asc->asc_txbuf_list, sizeof (struct ath_buf),
412 	    offsetof(struct ath_buf, bf_node));
413 	for (i = 0; i < ATH_TXBUF; i++, bf++, ds++) {
414 		bf->bf_desc = ds;
415 		bf->bf_daddr = asc->asc_desc_dma.cookie.dmac_address +
416 		    ((caddr_t)ds - (caddr_t)asc->asc_desc);
417 		list_insert_tail(&asc->asc_txbuf_list, bf);
418 
419 		/* alloc DMA memory */
420 		err = ath_alloc_dma_mem(devinfo, asc->asc_dmabuf_size,
421 		    &ath_desc_accattr,
422 		    DDI_DMA_STREAMING, DDI_DMA_STREAMING, &bf->bf_dma);
423 		if (err != DDI_SUCCESS)
424 			return (err);
425 	}
426 
427 	return (DDI_SUCCESS);
428 }
429 
430 static void
431 ath_desc_free(ath_t *asc)
432 {
433 	struct ath_buf *bf;
434 
435 	/* Free TX DMA buffer */
436 	bf = list_head(&asc->asc_txbuf_list);
437 	while (bf != NULL) {
438 		ath_free_dma_mem(&bf->bf_dma);
439 		list_remove(&asc->asc_txbuf_list, bf);
440 		bf = list_head(&asc->asc_txbuf_list);
441 	}
442 	list_destroy(&asc->asc_txbuf_list);
443 
444 	/* Free RX DMA uffer */
445 	bf = list_head(&asc->asc_rxbuf_list);
446 	while (bf != NULL) {
447 		ath_free_dma_mem(&bf->bf_dma);
448 		list_remove(&asc->asc_rxbuf_list, bf);
449 		bf = list_head(&asc->asc_rxbuf_list);
450 	}
451 	list_destroy(&asc->asc_rxbuf_list);
452 
453 	/* Free descriptor DMA buffer */
454 	ath_free_dma_mem(&asc->asc_desc_dma);
455 
456 	kmem_free((void *)asc->asc_vbufptr, asc->asc_vbuflen);
457 	asc->asc_vbufptr = NULL;
458 }
459 
460 static void
461 ath_printrxbuf(struct ath_buf *bf, int32_t done)
462 {
463 	struct ath_desc *ds = bf->bf_desc;
464 
465 	ATH_DEBUG((ATH_DBG_RECV, "ath: R (%p %p) %08x %08x %08x "
466 	    "%08x %08x %08x %c\n",
467 	    ds, bf->bf_daddr,
468 	    ds->ds_link, ds->ds_data,
469 	    ds->ds_ctl0, ds->ds_ctl1,
470 	    ds->ds_hw[0], ds->ds_hw[1],
471 	    !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!'));
472 }
473 
474 static void
475 ath_rx_handler(ath_t *asc)
476 {
477 	ieee80211com_t *ic = (ieee80211com_t *)asc;
478 	struct ath_buf *bf;
479 	struct ath_hal *ah = asc->asc_ah;
480 	struct ath_desc *ds;
481 	mblk_t *rx_mp;
482 	struct ieee80211_frame *wh;
483 	int32_t len, loop = 1;
484 	uint8_t phyerr;
485 	HAL_STATUS status;
486 	HAL_NODE_STATS hal_node_stats;
487 	struct ieee80211_node *in;
488 
489 	do {
490 		mutex_enter(&asc->asc_rxbuflock);
491 		bf = list_head(&asc->asc_rxbuf_list);
492 		if (bf == NULL) {
493 			ATH_DEBUG((ATH_DBG_RECV, "ath: ath_rx_handler(): "
494 			    "no buffer\n"));
495 			mutex_exit(&asc->asc_rxbuflock);
496 			break;
497 		}
498 		ASSERT(bf->bf_dma.cookie.dmac_address != NULL);
499 		ds = bf->bf_desc;
500 		if (ds->ds_link == bf->bf_daddr) {
501 			/*
502 			 * Never process the self-linked entry at the end,
503 			 * this may be met at heavy load.
504 			 */
505 			mutex_exit(&asc->asc_rxbuflock);
506 			break;
507 		}
508 
509 		status = ATH_HAL_RXPROCDESC(ah, ds,
510 		    bf->bf_daddr,
511 		    ATH_PA2DESC(asc, ds->ds_link));
512 		if (status == HAL_EINPROGRESS) {
513 			mutex_exit(&asc->asc_rxbuflock);
514 			break;
515 		}
516 		list_remove(&asc->asc_rxbuf_list, bf);
517 		mutex_exit(&asc->asc_rxbuflock);
518 
519 		if (ds->ds_rxstat.rs_status != 0) {
520 			if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
521 				asc->asc_stats.ast_rx_crcerr++;
522 			if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO)
523 				asc->asc_stats.ast_rx_fifoerr++;
524 			if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT)
525 				asc->asc_stats.ast_rx_badcrypt++;
526 			if (ds->ds_rxstat.rs_status & HAL_RXERR_PHY) {
527 				asc->asc_stats.ast_rx_phyerr++;
528 				phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
529 				asc->asc_stats.ast_rx_phy[phyerr]++;
530 			}
531 			goto rx_next;
532 		}
533 		len = ds->ds_rxstat.rs_datalen;
534 
535 		/* less than sizeof(struct ieee80211_frame) */
536 		if (len < 20) {
537 			asc->asc_stats.ast_rx_tooshort++;
538 			goto rx_next;
539 		}
540 
541 		if ((rx_mp = allocb(asc->asc_dmabuf_size, BPRI_MED)) == NULL) {
542 			ath_problem("ath: ath_rx_handler(): "
543 			    "allocing mblk buffer failed.\n");
544 			return;
545 		}
546 
547 		ATH_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORCPU);
548 		bcopy(bf->bf_dma.mem_va, rx_mp->b_rptr, len);
549 
550 		rx_mp->b_wptr += len;
551 		wh = (struct ieee80211_frame *)rx_mp->b_rptr;
552 		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
553 		    IEEE80211_FC0_TYPE_CTL) {
554 			/*
555 			 * Ignore control frame received in promisc mode.
556 			 */
557 			freemsg(rx_mp);
558 			goto rx_next;
559 		}
560 		/* Remove the CRC at the end of IEEE80211 frame */
561 		rx_mp->b_wptr -= IEEE80211_CRC_LEN;
562 #ifdef DEBUG
563 		ath_printrxbuf(bf, status == HAL_OK);
564 #endif /* DEBUG */
565 		/*
566 		 * Locate the node for sender, track state, and then
567 		 * pass the (referenced) node up to the 802.11 layer
568 		 * for its use.
569 		 */
570 		in = ieee80211_find_rxnode(ic, wh);
571 
572 		/*
573 		 * Send frame up for processing.
574 		 */
575 		(void) ieee80211_input(ic, rx_mp, in,
576 		    ds->ds_rxstat.rs_rssi,
577 		    ds->ds_rxstat.rs_tstamp);
578 
579 		ieee80211_free_node(in);
580 
581 rx_next:
582 		mutex_enter(&asc->asc_rxbuflock);
583 		list_insert_tail(&asc->asc_rxbuf_list, bf);
584 		mutex_exit(&asc->asc_rxbuflock);
585 		ath_setup_desc(asc, bf);
586 	} while (loop);
587 
588 	/* rx signal state monitoring */
589 	ATH_HAL_RXMONITOR(ah, &hal_node_stats, &asc->asc_curchan);
590 }
591 
592 static void
593 ath_printtxbuf(struct ath_buf *bf, int done)
594 {
595 	struct ath_desc *ds = bf->bf_desc;
596 
597 	ATH_DEBUG((ATH_DBG_SEND, "ath: T(%p %p) %08x %08x %08x %08x %08x"
598 	    " %08x %08x %08x %c\n",
599 	    ds, bf->bf_daddr,
600 	    ds->ds_link, ds->ds_data,
601 	    ds->ds_ctl0, ds->ds_ctl1,
602 	    ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
603 	    !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'));
604 }
605 
606 /*
607  * The input parameter mp has following assumption:
608  * For data packets, GLDv3 mac_wifi plugin allocates and fills the
609  * ieee80211 header. For management packets, net80211 allocates and
610  * fills the ieee80211 header. In both cases, enough spaces in the
611  * header are left for encryption option.
612  */
613 static int32_t
614 ath_tx_start(ath_t *asc, struct ieee80211_node *in, struct ath_buf *bf,
615     mblk_t *mp)
616 {
617 	ieee80211com_t *ic = (ieee80211com_t *)asc;
618 	struct ieee80211_frame *wh;
619 	struct ath_hal *ah = asc->asc_ah;
620 	uint32_t subtype, flags, ctsduration;
621 	int32_t keyix, iswep, hdrlen, pktlen, mblen, mbslen, try0;
622 	uint8_t rix, cix, txrate, ctsrate;
623 	struct ath_desc *ds;
624 	struct ath_txq *txq;
625 	HAL_PKT_TYPE atype;
626 	const HAL_RATE_TABLE *rt;
627 	HAL_BOOL shortPreamble;
628 	struct ath_node *an;
629 	caddr_t dest;
630 
631 	/*
632 	 * CRC are added by H/W, not encaped by driver,
633 	 * but we must count it in pkt length.
634 	 */
635 	pktlen = IEEE80211_CRC_LEN;
636 
637 	wh = (struct ieee80211_frame *)mp->b_rptr;
638 	iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
639 	keyix = HAL_TXKEYIX_INVALID;
640 	hdrlen = sizeof (struct ieee80211_frame);
641 	if (iswep != 0) {
642 		const struct ieee80211_cipher *cip;
643 		struct ieee80211_key *k;
644 
645 		/*
646 		 * Construct the 802.11 header+trailer for an encrypted
647 		 * frame. The only reason this can fail is because of an
648 		 * unknown or unsupported cipher/key type.
649 		 */
650 		k = ieee80211_crypto_encap(ic, mp);
651 		if (k == NULL) {
652 			ATH_DEBUG((ATH_DBG_AUX, "crypto_encap failed\n"));
653 			/*
654 			 * This can happen when the key is yanked after the
655 			 * frame was queued.  Just discard the frame; the
656 			 * 802.11 layer counts failures and provides
657 			 * debugging/diagnostics.
658 			 */
659 			return (EIO);
660 		}
661 		cip = k->wk_cipher;
662 		/*
663 		 * Adjust the packet + header lengths for the crypto
664 		 * additions and calculate the h/w key index.  When
665 		 * a s/w mic is done the frame will have had any mic
666 		 * added to it prior to entry so m0->m_pkthdr.len above will
667 		 * account for it. Otherwise we need to add it to the
668 		 * packet length.
669 		 */
670 		hdrlen += cip->ic_header;
671 		pktlen += cip->ic_trailer;
672 		if ((k->wk_flags & IEEE80211_KEY_SWMIC) == 0)
673 			pktlen += cip->ic_miclen;
674 		keyix = k->wk_keyix;
675 
676 		/* packet header may have moved, reset our local pointer */
677 		wh = (struct ieee80211_frame *)mp->b_rptr;
678 	}
679 
680 	dest = bf->bf_dma.mem_va;
681 	for (; mp != NULL; mp = mp->b_cont) {
682 		mblen = MBLKL(mp);
683 		bcopy(mp->b_rptr, dest, mblen);
684 		dest += mblen;
685 	}
686 	mbslen = dest - bf->bf_dma.mem_va;
687 	pktlen += mbslen;
688 
689 	bf->bf_in = in;
690 
691 	/* setup descriptors */
692 	ds = bf->bf_desc;
693 	rt = asc->asc_currates;
694 	ASSERT(rt != NULL);
695 
696 	/*
697 	 * The 802.11 layer marks whether or not we should
698 	 * use short preamble based on the current mode and
699 	 * negotiated parameters.
700 	 */
701 	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
702 	    (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
703 		shortPreamble = AH_TRUE;
704 		asc->asc_stats.ast_tx_shortpre++;
705 	} else {
706 		shortPreamble = AH_FALSE;
707 	}
708 
709 	an = ATH_NODE(in);
710 
711 	/*
712 	 * Calculate Atheros packet type from IEEE80211 packet header
713 	 * and setup for rate calculations.
714 	 */
715 	switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
716 	case IEEE80211_FC0_TYPE_MGT:
717 		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
718 		if (subtype == IEEE80211_FC0_SUBTYPE_BEACON)
719 			atype = HAL_PKT_TYPE_BEACON;
720 		else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
721 			atype = HAL_PKT_TYPE_PROBE_RESP;
722 		else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM)
723 			atype = HAL_PKT_TYPE_ATIM;
724 		else
725 			atype = HAL_PKT_TYPE_NORMAL;
726 		rix = 0;	/* lowest rate */
727 		try0 = ATH_TXMAXTRY;
728 		if (shortPreamble)
729 			txrate = an->an_tx_mgtratesp;
730 		else
731 			txrate = an->an_tx_mgtrate;
732 		/* force all ctl frames to highest queue */
733 		txq = asc->asc_ac2q[WME_AC_VO];
734 		break;
735 	case IEEE80211_FC0_TYPE_CTL:
736 		atype = HAL_PKT_TYPE_PSPOLL;
737 		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
738 		rix = 0;	/* lowest rate */
739 		try0 = ATH_TXMAXTRY;
740 		if (shortPreamble)
741 			txrate = an->an_tx_mgtratesp;
742 		else
743 			txrate = an->an_tx_mgtrate;
744 		/* force all ctl frames to highest queue */
745 		txq = asc->asc_ac2q[WME_AC_VO];
746 		break;
747 	case IEEE80211_FC0_TYPE_DATA:
748 		atype = HAL_PKT_TYPE_NORMAL;
749 		rix = an->an_tx_rix0;
750 		try0 = an->an_tx_try0;
751 		if (shortPreamble)
752 			txrate = an->an_tx_rate0sp;
753 		else
754 			txrate = an->an_tx_rate0;
755 		/* Always use background queue */
756 		txq = asc->asc_ac2q[WME_AC_BK];
757 		break;
758 	default:
759 		/* Unknown 802.11 frame */
760 		asc->asc_stats.ast_tx_invalid++;
761 		return (1);
762 	}
763 	/*
764 	 * Calculate miscellaneous flags.
765 	 */
766 	flags = HAL_TXDESC_CLRDMASK;
767 	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
768 		flags |= HAL_TXDESC_NOACK;	/* no ack on broad/multicast */
769 		asc->asc_stats.ast_tx_noack++;
770 	} else if (pktlen > ic->ic_rtsthreshold) {
771 		flags |= HAL_TXDESC_RTSENA;	/* RTS based on frame length */
772 		asc->asc_stats.ast_tx_rts++;
773 	}
774 
775 	/*
776 	 * Calculate duration.  This logically belongs in the 802.11
777 	 * layer but it lacks sufficient information to calculate it.
778 	 */
779 	if ((flags & HAL_TXDESC_NOACK) == 0 &&
780 	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
781 	    IEEE80211_FC0_TYPE_CTL) {
782 		uint16_t dur;
783 		dur = ath_hal_computetxtime(ah, rt, IEEE80211_ACK_SIZE,
784 		    rix, shortPreamble);
785 		*(uint16_t *)wh->i_dur = LE_16(dur);
786 	}
787 
788 	/*
789 	 * Calculate RTS/CTS rate and duration if needed.
790 	 */
791 	ctsduration = 0;
792 	if (flags & (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)) {
793 		/*
794 		 * CTS transmit rate is derived from the transmit rate
795 		 * by looking in the h/w rate table.  We must also factor
796 		 * in whether or not a short preamble is to be used.
797 		 */
798 		cix = rt->info[rix].controlRate;
799 		ctsrate = rt->info[cix].rateCode;
800 		if (shortPreamble)
801 			ctsrate |= rt->info[cix].shortPreamble;
802 		/*
803 		 * Compute the transmit duration based on the size
804 		 * of an ACK frame.  We call into the HAL to do the
805 		 * computation since it depends on the characteristics
806 		 * of the actual PHY being used.
807 		 */
808 		if (flags & HAL_TXDESC_RTSENA) {	/* SIFS + CTS */
809 			ctsduration += ath_hal_computetxtime(ah,
810 			    rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
811 		}
812 		/* SIFS + data */
813 		ctsduration += ath_hal_computetxtime(ah,
814 		    rt, pktlen, rix, shortPreamble);
815 		if ((flags & HAL_TXDESC_NOACK) == 0) {	/* SIFS + ACK */
816 			ctsduration += ath_hal_computetxtime(ah,
817 			    rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
818 		}
819 	} else
820 		ctsrate = 0;
821 
822 	if (++txq->axq_intrcnt >= ATH_TXINTR_PERIOD) {
823 		flags |= HAL_TXDESC_INTREQ;
824 		txq->axq_intrcnt = 0;
825 	}
826 
827 	/*
828 	 * Formulate first tx descriptor with tx controls.
829 	 */
830 	ATH_HAL_SETUPTXDESC(ah, ds,
831 	    pktlen,			/* packet length */
832 	    hdrlen,			/* header length */
833 	    atype,			/* Atheros packet type */
834 	    MIN(in->in_txpower, 60),	/* txpower */
835 	    txrate, try0,		/* series 0 rate/tries */
836 	    keyix,			/* key cache index */
837 	    an->an_tx_antenna,		/* antenna mode */
838 	    flags,			/* flags */
839 	    ctsrate,			/* rts/cts rate */
840 	    ctsduration);		/* rts/cts duration */
841 	bf->bf_flags = flags;
842 
843 	ATH_DEBUG((ATH_DBG_SEND, "ath: ath_xmit(): to %s totlen=%d "
844 	    "an->an_tx_rate1sp=%d tx_rate2sp=%d tx_rate3sp=%d "
845 	    "qnum=%d rix=%d sht=%d dur = %d\n",
846 	    ieee80211_macaddr_sprintf(wh->i_addr1), mbslen, an->an_tx_rate1sp,
847 	    an->an_tx_rate2sp, an->an_tx_rate3sp,
848 	    txq->axq_qnum, rix, shortPreamble, *(uint16_t *)wh->i_dur));
849 
850 	/*
851 	 * Setup the multi-rate retry state only when we're
852 	 * going to use it.  This assumes ath_hal_setuptxdesc
853 	 * initializes the descriptors (so we don't have to)
854 	 * when the hardware supports multi-rate retry and
855 	 * we don't use it.
856 	 */
857 	if (try0 != ATH_TXMAXTRY)
858 		ATH_HAL_SETUPXTXDESC(ah, ds,
859 		    an->an_tx_rate1sp, 2,	/* series 1 */
860 		    an->an_tx_rate2sp, 2,	/* series 2 */
861 		    an->an_tx_rate3sp, 2);	/* series 3 */
862 
863 	ds->ds_link = 0;
864 	ds->ds_data = bf->bf_dma.cookie.dmac_address;
865 	ATH_HAL_FILLTXDESC(ah, ds,
866 	    mbslen,		/* segment length */
867 	    AH_TRUE,		/* first segment */
868 	    AH_TRUE,		/* last segment */
869 	    ds);		/* first descriptor */
870 
871 	ATH_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV);
872 
873 	mutex_enter(&txq->axq_lock);
874 	list_insert_tail(&txq->axq_list, bf);
875 	if (txq->axq_link == NULL) {
876 		ATH_HAL_PUTTXBUF(ah, txq->axq_qnum, bf->bf_daddr);
877 	} else {
878 		*txq->axq_link = bf->bf_daddr;
879 	}
880 	txq->axq_link = &ds->ds_link;
881 	mutex_exit(&txq->axq_lock);
882 
883 	ATH_HAL_TXSTART(ah, txq->axq_qnum);
884 
885 	ic->ic_stats.is_tx_frags++;
886 	ic->ic_stats.is_tx_bytes += pktlen;
887 
888 	return (0);
889 }
890 
891 /*
892  * Transmit a management frame.  On failure we reclaim the skbuff.
893  * Note that management frames come directly from the 802.11 layer
894  * and do not honor the send queue flow control.  Need to investigate
895  * using priority queueing so management frames can bypass data.
896  */
897 static int
898 ath_xmit(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
899 {
900 	ath_t *asc = (ath_t *)ic;
901 	struct ath_hal *ah = asc->asc_ah;
902 	struct ieee80211_node *in = NULL;
903 	struct ath_buf *bf = NULL;
904 	struct ieee80211_frame *wh;
905 	int error = 0;
906 
907 	ASSERT(mp->b_next == NULL);
908 
909 	/* Grab a TX buffer */
910 	mutex_enter(&asc->asc_txbuflock);
911 	bf = list_head(&asc->asc_txbuf_list);
912 	if (bf != NULL)
913 		list_remove(&asc->asc_txbuf_list, bf);
914 	if (list_empty(&asc->asc_txbuf_list)) {
915 		ATH_DEBUG((ATH_DBG_SEND, "ath: ath_mgmt_send(): "
916 		    "stop queue\n"));
917 		asc->asc_stats.ast_tx_qstop++;
918 	}
919 	mutex_exit(&asc->asc_txbuflock);
920 	if (bf == NULL) {
921 		ATH_DEBUG((ATH_DBG_SEND, "ath: ath_mgmt_send(): discard, "
922 		    "no xmit buf\n"));
923 		ic->ic_stats.is_tx_nobuf++;
924 		if ((type & IEEE80211_FC0_TYPE_MASK) ==
925 		    IEEE80211_FC0_TYPE_DATA) {
926 			asc->asc_stats.ast_tx_nobuf++;
927 			mutex_enter(&asc->asc_resched_lock);
928 			asc->asc_resched_needed = B_TRUE;
929 			mutex_exit(&asc->asc_resched_lock);
930 		} else {
931 			asc->asc_stats.ast_tx_nobufmgt++;
932 			freemsg(mp);
933 		}
934 		return (ENOMEM);
935 	}
936 
937 	wh = (struct ieee80211_frame *)mp->b_rptr;
938 
939 	/* Locate node */
940 	in = ieee80211_find_txnode(ic,  wh->i_addr1);
941 	if (in == NULL) {
942 		error = EIO;
943 		goto bad;
944 	}
945 
946 	in->in_inact = 0;
947 	switch (type & IEEE80211_FC0_TYPE_MASK) {
948 	case IEEE80211_FC0_TYPE_DATA:
949 		(void) ieee80211_encap(ic, mp, in);
950 		break;
951 	default:
952 		if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
953 		    IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
954 			/* fill time stamp */
955 			uint64_t tsf;
956 			uint32_t *tstamp;
957 
958 			tsf = ATH_HAL_GETTSF64(ah);
959 			/* adjust 100us delay to xmit */
960 			tsf += 100;
961 			tstamp = (uint32_t *)&wh[1];
962 			tstamp[0] = LE_32(tsf & 0xffffffff);
963 			tstamp[1] = LE_32(tsf >> 32);
964 		}
965 		asc->asc_stats.ast_tx_mgmt++;
966 		break;
967 	}
968 
969 	error = ath_tx_start(asc, in, bf, mp);
970 	if (error != 0) {
971 bad:
972 		ic->ic_stats.is_tx_failed++;
973 		if (bf != NULL) {
974 			mutex_enter(&asc->asc_txbuflock);
975 			list_insert_tail(&asc->asc_txbuf_list, bf);
976 			mutex_exit(&asc->asc_txbuflock);
977 		}
978 	}
979 	if (in != NULL)
980 		ieee80211_free_node(in);
981 	if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
982 	    error == 0) {
983 		freemsg(mp);
984 	}
985 
986 	return (error);
987 }
988 
989 static mblk_t *
990 ath_m_tx(void *arg, mblk_t *mp)
991 {
992 	ath_t *asc = arg;
993 	ieee80211com_t *ic = (ieee80211com_t *)asc;
994 	mblk_t *next;
995 	int error = 0;
996 
997 	/*
998 	 * No data frames go out unless we're associated; this
999 	 * should not happen as the 802.11 layer does not enable
1000 	 * the xmit queue until we enter the RUN state.
1001 	 */
1002 	if (ic->ic_state != IEEE80211_S_RUN) {
1003 		ATH_DEBUG((ATH_DBG_SEND, "ath: ath_m_tx(): "
1004 		    "discard, state %u\n", ic->ic_state));
1005 		asc->asc_stats.ast_tx_discard++;
1006 		freemsgchain(mp);
1007 		return (NULL);
1008 	}
1009 
1010 	while (mp != NULL) {
1011 		next = mp->b_next;
1012 		mp->b_next = NULL;
1013 		error = ath_xmit(ic, mp, IEEE80211_FC0_TYPE_DATA);
1014 		if (error != 0) {
1015 			mp->b_next = next;
1016 			if (error == ENOMEM) {
1017 				break;
1018 			} else {
1019 				freemsgchain(mp);	/* CR6501759 issues */
1020 				return (NULL);
1021 			}
1022 		}
1023 		mp = next;
1024 	}
1025 
1026 	return (mp);
1027 
1028 }
1029 
1030 static int
1031 ath_tx_processq(ath_t *asc, struct ath_txq *txq)
1032 {
1033 	ieee80211com_t *ic = (ieee80211com_t *)asc;
1034 	struct ath_hal *ah = asc->asc_ah;
1035 	struct ath_buf *bf;
1036 	struct ath_desc *ds;
1037 	struct ieee80211_node *in;
1038 	int32_t sr, lr, nacked = 0;
1039 	HAL_STATUS status;
1040 	struct ath_node *an;
1041 
1042 	for (;;) {
1043 		mutex_enter(&txq->axq_lock);
1044 		bf = list_head(&txq->axq_list);
1045 		if (bf == NULL) {
1046 			txq->axq_link = NULL;
1047 			mutex_exit(&txq->axq_lock);
1048 			break;
1049 		}
1050 		ds = bf->bf_desc;	/* last decriptor */
1051 		status = ATH_HAL_TXPROCDESC(ah, ds);
1052 #ifdef DEBUG
1053 		ath_printtxbuf(bf, status == HAL_OK);
1054 #endif
1055 		if (status == HAL_EINPROGRESS) {
1056 			mutex_exit(&txq->axq_lock);
1057 			break;
1058 		}
1059 		list_remove(&txq->axq_list, bf);
1060 		mutex_exit(&txq->axq_lock);
1061 		in = bf->bf_in;
1062 		if (in != NULL) {
1063 			an = ATH_NODE(in);
1064 			/* Successful transmition */
1065 			if (ds->ds_txstat.ts_status == 0) {
1066 				an->an_tx_ok++;
1067 				an->an_tx_antenna =
1068 				    ds->ds_txstat.ts_antenna;
1069 				if (ds->ds_txstat.ts_rate &
1070 				    HAL_TXSTAT_ALTRATE)
1071 					asc->asc_stats.ast_tx_altrate++;
1072 				asc->asc_stats.ast_tx_rssidelta =
1073 				    ds->ds_txstat.ts_rssi -
1074 				    asc->asc_stats.ast_tx_rssi;
1075 				asc->asc_stats.ast_tx_rssi =
1076 				    ds->ds_txstat.ts_rssi;
1077 			} else {
1078 				an->an_tx_err++;
1079 				if (ds->ds_txstat.ts_status &
1080 				    HAL_TXERR_XRETRY)
1081 					asc->asc_stats.
1082 					    ast_tx_xretries++;
1083 				if (ds->ds_txstat.ts_status &
1084 				    HAL_TXERR_FIFO)
1085 					asc->asc_stats.ast_tx_fifoerr++;
1086 				if (ds->ds_txstat.ts_status &
1087 				    HAL_TXERR_FILT)
1088 					asc->asc_stats.
1089 					    ast_tx_filtered++;
1090 				an->an_tx_antenna = 0;	/* invalidate */
1091 			}
1092 			sr = ds->ds_txstat.ts_shortretry;
1093 			lr = ds->ds_txstat.ts_longretry;
1094 			asc->asc_stats.ast_tx_shortretry += sr;
1095 			asc->asc_stats.ast_tx_longretry += lr;
1096 			/*
1097 			 * Hand the descriptor to the rate control algorithm.
1098 			 */
1099 			if ((ds->ds_txstat.ts_status & HAL_TXERR_FILT) == 0 &&
1100 			    (bf->bf_flags & HAL_TXDESC_NOACK) == 0) {
1101 				/*
1102 				 * If frame was ack'd update the last rx time
1103 				 * used to workaround phantom bmiss interrupts.
1104 				 */
1105 				if (ds->ds_txstat.ts_status == 0) {
1106 					nacked++;
1107 					an->an_tx_ok++;
1108 				} else {
1109 					an->an_tx_err++;
1110 				}
1111 				an->an_tx_retr += sr + lr;
1112 			}
1113 		}
1114 		bf->bf_in = NULL;
1115 		mutex_enter(&asc->asc_txbuflock);
1116 		list_insert_tail(&asc->asc_txbuf_list, bf);
1117 		mutex_exit(&asc->asc_txbuflock);
1118 		/*
1119 		 * Reschedule stalled outbound packets
1120 		 */
1121 		mutex_enter(&asc->asc_resched_lock);
1122 		if (asc->asc_resched_needed) {
1123 			asc->asc_resched_needed = B_FALSE;
1124 			mac_tx_update(ic->ic_mach);
1125 		}
1126 		mutex_exit(&asc->asc_resched_lock);
1127 	}
1128 	return (nacked);
1129 }
1130 
1131 
1132 static void
1133 ath_tx_handler(ath_t *asc)
1134 {
1135 	int i;
1136 
1137 	/*
1138 	 * Process each active queue.
1139 	 */
1140 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
1141 		if (ATH_TXQ_SETUP(asc, i)) {
1142 			(void) ath_tx_processq(asc, &asc->asc_txq[i]);
1143 		}
1144 	}
1145 }
1146 
1147 static struct ieee80211_node *
1148 ath_node_alloc(ieee80211com_t *ic)
1149 {
1150 	struct ath_node *an;
1151 	ath_t *asc = (ath_t *)ic;
1152 
1153 	an = kmem_zalloc(sizeof (struct ath_node), KM_SLEEP);
1154 	ath_rate_update(asc, &an->an_node, 0);
1155 	return (&an->an_node);
1156 }
1157 
1158 static void
1159 ath_node_free(struct ieee80211_node *in)
1160 {
1161 	ieee80211com_t *ic = in->in_ic;
1162 	ath_t *asc = (ath_t *)ic;
1163 	struct ath_buf *bf;
1164 	struct ath_txq *txq;
1165 	int32_t i;
1166 
1167 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
1168 		if (ATH_TXQ_SETUP(asc, i)) {
1169 			txq = &asc->asc_txq[i];
1170 			mutex_enter(&txq->axq_lock);
1171 			bf = list_head(&txq->axq_list);
1172 			while (bf != NULL) {
1173 				if (bf->bf_in == in) {
1174 					bf->bf_in = NULL;
1175 				}
1176 				bf = list_next(&txq->axq_list, bf);
1177 			}
1178 			mutex_exit(&txq->axq_lock);
1179 		}
1180 	}
1181 	ic->ic_node_cleanup(in);
1182 	if (in->in_wpa_ie != NULL)
1183 		ieee80211_free(in->in_wpa_ie);
1184 	kmem_free(in, sizeof (struct ath_node));
1185 }
1186 
1187 static void
1188 ath_next_scan(void *arg)
1189 {
1190 	ieee80211com_t *ic = arg;
1191 	ath_t *asc = (ath_t *)ic;
1192 
1193 	asc->asc_scan_timer = 0;
1194 	if (ic->ic_state == IEEE80211_S_SCAN) {
1195 		asc->asc_scan_timer = timeout(ath_next_scan, (void *)asc,
1196 		    drv_usectohz(ath_dwelltime * 1000));
1197 		ieee80211_next_scan(ic);
1198 	}
1199 }
1200 
1201 static void
1202 ath_stop_scantimer(ath_t *asc)
1203 {
1204 	timeout_id_t tmp_id = 0;
1205 
1206 	while ((asc->asc_scan_timer != 0) && (tmp_id != asc->asc_scan_timer)) {
1207 		tmp_id = asc->asc_scan_timer;
1208 		(void) untimeout(tmp_id);
1209 	}
1210 	asc->asc_scan_timer = 0;
1211 }
1212 
1213 static int32_t
1214 ath_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
1215 {
1216 	ath_t *asc = (ath_t *)ic;
1217 	struct ath_hal *ah = asc->asc_ah;
1218 	struct ieee80211_node *in;
1219 	int32_t i, error;
1220 	uint8_t *bssid;
1221 	uint32_t rfilt;
1222 	enum ieee80211_state ostate;
1223 
1224 	static const HAL_LED_STATE leds[] = {
1225 	    HAL_LED_INIT,	/* IEEE80211_S_INIT */
1226 	    HAL_LED_SCAN,	/* IEEE80211_S_SCAN */
1227 	    HAL_LED_AUTH,	/* IEEE80211_S_AUTH */
1228 	    HAL_LED_ASSOC, 	/* IEEE80211_S_ASSOC */
1229 	    HAL_LED_RUN, 	/* IEEE80211_S_RUN */
1230 	};
1231 	if (!ATH_IS_RUNNING(asc))
1232 		return (0);
1233 
1234 	ostate = ic->ic_state;
1235 	if (nstate != IEEE80211_S_SCAN)
1236 		ath_stop_scantimer(asc);
1237 
1238 	ATH_LOCK(asc);
1239 	ATH_HAL_SETLEDSTATE(ah, leds[nstate]);	/* set LED */
1240 
1241 	if (nstate == IEEE80211_S_INIT) {
1242 		asc->asc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
1243 		ATH_HAL_INTRSET(ah, asc->asc_imask &~ HAL_INT_GLOBAL);
1244 		ATH_UNLOCK(asc);
1245 		goto done;
1246 	}
1247 	in = ic->ic_bss;
1248 	error = ath_chan_set(asc, ic->ic_curchan);
1249 	if (error != 0) {
1250 		if (nstate != IEEE80211_S_SCAN) {
1251 			ATH_UNLOCK(asc);
1252 			ieee80211_reset_chan(ic);
1253 			goto bad;
1254 		}
1255 	}
1256 
1257 	rfilt = ath_calcrxfilter(asc);
1258 	if (nstate == IEEE80211_S_SCAN)
1259 		bssid = ic->ic_macaddr;
1260 	else
1261 		bssid = in->in_bssid;
1262 	ATH_HAL_SETRXFILTER(ah, rfilt);
1263 
1264 	if (nstate == IEEE80211_S_RUN && ic->ic_opmode != IEEE80211_M_IBSS)
1265 		ATH_HAL_SETASSOCID(ah, bssid, in->in_associd);
1266 	else
1267 		ATH_HAL_SETASSOCID(ah, bssid, 0);
1268 	if (ic->ic_flags & IEEE80211_F_PRIVACY) {
1269 		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1270 			if (ATH_HAL_KEYISVALID(ah, i))
1271 				ATH_HAL_KEYSETMAC(ah, i, bssid);
1272 		}
1273 	}
1274 
1275 	if ((nstate == IEEE80211_S_RUN) &&
1276 	    (ostate != IEEE80211_S_RUN)) {
1277 		/* Configure the beacon and sleep timers. */
1278 		ath_beacon_config(asc);
1279 	} else {
1280 		asc->asc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
1281 		ATH_HAL_INTRSET(ah, asc->asc_imask);
1282 	}
1283 	/*
1284 	 * Reset the rate control state.
1285 	 */
1286 	ath_rate_ctl_reset(asc, nstate);
1287 
1288 	if (nstate == IEEE80211_S_RUN && (ostate != IEEE80211_S_RUN)) {
1289 		nvlist_t *attr_list = NULL;
1290 		sysevent_id_t eid;
1291 		int32_t err = 0;
1292 		char *str_name = "ATH";
1293 		char str_value[256] = {0};
1294 
1295 		ATH_DEBUG((ATH_DBG_80211, "ath: ath new state(RUN): "
1296 		    "ic_flags=0x%08x iv=%d"
1297 		    " bssid=%s capinfo=0x%04x chan=%d\n",
1298 		    ic->ic_flags,
1299 		    in->in_intval,
1300 		    ieee80211_macaddr_sprintf(in->in_bssid),
1301 		    in->in_capinfo,
1302 		    ieee80211_chan2ieee(ic, in->in_chan)));
1303 
1304 		(void) sprintf(str_value, "%s%s%d", "-i ",
1305 		    ddi_driver_name(asc->asc_dev),
1306 		    ddi_get_instance(asc->asc_dev));
1307 		if (nvlist_alloc(&attr_list,
1308 		    NV_UNIQUE_NAME_TYPE, KM_SLEEP) == 0) {
1309 			err = nvlist_add_string(attr_list,
1310 			    str_name, str_value);
1311 			if (err != DDI_SUCCESS)
1312 				ATH_DEBUG((ATH_DBG_80211, "ath: "
1313 				    "ath_new_state: error log event\n"));
1314 			err = ddi_log_sysevent(asc->asc_dev,
1315 			    DDI_VENDOR_SUNW, "class",
1316 			    "subclass", attr_list,
1317 			    &eid, DDI_NOSLEEP);
1318 			if (err != DDI_SUCCESS)
1319 				ATH_DEBUG((ATH_DBG_80211, "ath: "
1320 				    "ath_new_state(): error log event\n"));
1321 			nvlist_free(attr_list);
1322 		}
1323 	}
1324 
1325 	ATH_UNLOCK(asc);
1326 done:
1327 	/*
1328 	 * Invoke the parent method to complete the work.
1329 	 */
1330 	error = asc->asc_newstate(ic, nstate, arg);
1331 	/*
1332 	 * Finally, start any timers.
1333 	 */
1334 	if (nstate == IEEE80211_S_RUN) {
1335 		ieee80211_start_watchdog(ic, 1);
1336 	} else if ((nstate == IEEE80211_S_SCAN) && (ostate != nstate)) {
1337 		/* start ap/neighbor scan timer */
1338 		ASSERT(asc->asc_scan_timer == 0);
1339 		asc->asc_scan_timer = timeout(ath_next_scan, (void *)asc,
1340 		    drv_usectohz(ath_dwelltime * 1000));
1341 	}
1342 bad:
1343 	return (error);
1344 }
1345 
1346 /*
1347  * Periodically recalibrate the PHY to account
1348  * for temperature/environment changes.
1349  */
1350 static void
1351 ath_calibrate(ath_t *asc)
1352 {
1353 	struct ath_hal *ah = asc->asc_ah;
1354 	HAL_BOOL iqcaldone;
1355 
1356 	asc->asc_stats.ast_per_cal++;
1357 
1358 	if (ATH_HAL_GETRFGAIN(ah) == HAL_RFGAIN_NEED_CHANGE) {
1359 		/*
1360 		 * Rfgain is out of bounds, reset the chip
1361 		 * to load new gain values.
1362 		 */
1363 		ATH_DEBUG((ATH_DBG_HAL, "ath: ath_calibrate(): "
1364 		    "Need change RFgain\n"));
1365 		asc->asc_stats.ast_per_rfgain++;
1366 		(void) ath_reset(&asc->asc_isc);
1367 	}
1368 	if (!ATH_HAL_CALIBRATE(ah, &asc->asc_curchan, &iqcaldone)) {
1369 		ATH_DEBUG((ATH_DBG_HAL, "ath: ath_calibrate(): "
1370 		    "calibration of channel %u failed\n",
1371 		    asc->asc_curchan.channel));
1372 		asc->asc_stats.ast_per_calfail++;
1373 	}
1374 }
1375 
1376 static void
1377 ath_watchdog(void *arg)
1378 {
1379 	ath_t *asc = arg;
1380 	ieee80211com_t *ic = &asc->asc_isc;
1381 	int ntimer = 0;
1382 
1383 	ATH_LOCK(asc);
1384 	ic->ic_watchdog_timer = 0;
1385 	if (!ATH_IS_RUNNING(asc)) {
1386 		ATH_UNLOCK(asc);
1387 		return;
1388 	}
1389 
1390 	if (ic->ic_state == IEEE80211_S_RUN) {
1391 		/* periodic recalibration */
1392 		ath_calibrate(asc);
1393 
1394 		/*
1395 		 * Start the background rate control thread if we
1396 		 * are not configured to use a fixed xmit rate.
1397 		 */
1398 		if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
1399 			asc->asc_stats.ast_rate_calls ++;
1400 			if (ic->ic_opmode == IEEE80211_M_STA)
1401 				ath_rate_ctl(ic, ic->ic_bss);
1402 			else
1403 				ieee80211_iterate_nodes(&ic->ic_sta,
1404 				    ath_rate_cb, asc);
1405 		}
1406 
1407 		ntimer = 1;
1408 	}
1409 	ATH_UNLOCK(asc);
1410 
1411 	ieee80211_watchdog(ic);
1412 	if (ntimer != 0)
1413 		ieee80211_start_watchdog(ic, ntimer);
1414 }
1415 
1416 static uint_t
1417 ath_intr(caddr_t arg)
1418 {
1419 	ath_t *asc = (ath_t *)arg;
1420 	struct ath_hal *ah = asc->asc_ah;
1421 	HAL_INT status;
1422 	ieee80211com_t *ic = (ieee80211com_t *)asc;
1423 
1424 	ATH_LOCK(asc);
1425 
1426 	if (!ATH_IS_RUNNING(asc)) {
1427 		/*
1428 		 * The hardware is not ready/present, don't touch anything.
1429 		 * Note this can happen early on if the IRQ is shared.
1430 		 */
1431 		ATH_UNLOCK(asc);
1432 		return (DDI_INTR_UNCLAIMED);
1433 	}
1434 
1435 	if (!ATH_HAL_INTRPEND(ah)) {	/* shared irq, not for us */
1436 		ATH_UNLOCK(asc);
1437 		return (DDI_INTR_UNCLAIMED);
1438 	}
1439 
1440 	ATH_HAL_GETISR(ah, &status);
1441 	status &= asc->asc_imask;
1442 	if (status & HAL_INT_FATAL) {
1443 		asc->asc_stats.ast_hardware++;
1444 		goto reset;
1445 	} else if (status & HAL_INT_RXORN) {
1446 		asc->asc_stats.ast_rxorn++;
1447 		goto reset;
1448 	} else {
1449 		if (status & HAL_INT_RXEOL) {
1450 			asc->asc_stats.ast_rxeol++;
1451 			asc->asc_rxlink = NULL;
1452 		}
1453 		if (status & HAL_INT_TXURN) {
1454 			asc->asc_stats.ast_txurn++;
1455 			ATH_HAL_UPDATETXTRIGLEVEL(ah, AH_TRUE);
1456 		}
1457 
1458 		if (status & HAL_INT_RX) {
1459 			asc->asc_rx_pend = 1;
1460 			ddi_trigger_softintr(asc->asc_softint_id);
1461 		}
1462 		if (status & HAL_INT_TX) {
1463 			ath_tx_handler(asc);
1464 		}
1465 		ATH_UNLOCK(asc);
1466 
1467 		if (status & HAL_INT_SWBA) {
1468 			/* This will occur only in Host-AP or Ad-Hoc mode */
1469 			return (DDI_INTR_CLAIMED);
1470 		}
1471 		if (status & HAL_INT_BMISS) {
1472 			if (ic->ic_state == IEEE80211_S_RUN) {
1473 				(void) ieee80211_new_state(ic,
1474 				    IEEE80211_S_ASSOC, -1);
1475 			}
1476 		}
1477 	}
1478 
1479 	return (DDI_INTR_CLAIMED);
1480 reset:
1481 	(void) ath_reset(ic);
1482 	ATH_UNLOCK(asc);
1483 	return (DDI_INTR_CLAIMED);
1484 }
1485 
1486 static uint_t
1487 ath_softint_handler(caddr_t data)
1488 {
1489 	ath_t *asc = (ath_t *)data;
1490 
1491 	/*
1492 	 * Check if the soft interrupt is triggered by another
1493 	 * driver at the same level.
1494 	 */
1495 	ATH_LOCK(asc);
1496 	if (asc->asc_rx_pend) { /* Soft interrupt for this driver */
1497 		asc->asc_rx_pend = 0;
1498 		ATH_UNLOCK(asc);
1499 		ath_rx_handler(asc);
1500 		return (DDI_INTR_CLAIMED);
1501 	}
1502 	ATH_UNLOCK(asc);
1503 	return (DDI_INTR_UNCLAIMED);
1504 }
1505 
1506 /*
1507  * following are gld callback routine
1508  * ath_gld_send, ath_gld_ioctl, ath_gld_gstat
1509  * are listed in other corresponding sections.
1510  * reset the hardware w/o losing operational state.  this is
1511  * basically a more efficient way of doing ath_gld_stop, ath_gld_start,
1512  * followed by state transitions to the current 802.11
1513  * operational state.  used to recover from errors rx overrun
1514  * and to reset the hardware when rf gain settings must be reset.
1515  */
1516 
1517 static void
1518 ath_stop_locked(ath_t *asc)
1519 {
1520 	ieee80211com_t *ic = (ieee80211com_t *)asc;
1521 	struct ath_hal *ah = asc->asc_ah;
1522 
1523 	ATH_LOCK_ASSERT(asc);
1524 	/*
1525 	 * Shutdown the hardware and driver:
1526 	 *    reset 802.11 state machine
1527 	 *    turn off timers
1528 	 *    disable interrupts
1529 	 *    turn off the radio
1530 	 *    clear transmit machinery
1531 	 *    clear receive machinery
1532 	 *    drain and release tx queues
1533 	 *    reclaim beacon resources
1534 	 *    power down hardware
1535 	 *
1536 	 * Note that some of this work is not possible if the
1537 	 * hardware is gone (invalid).
1538 	 */
1539 	ATH_UNLOCK(asc);
1540 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1541 	ieee80211_stop_watchdog(ic);
1542 	ATH_LOCK(asc);
1543 	ATH_HAL_INTRSET(ah, 0);
1544 	ath_draintxq(asc);
1545 	if (ATH_IS_RUNNING(asc)) {
1546 		ath_stoprecv(asc);
1547 		ATH_HAL_PHYDISABLE(ah);
1548 	} else {
1549 		asc->asc_rxlink = NULL;
1550 	}
1551 }
1552 
1553 static void
1554 ath_m_stop(void *arg)
1555 {
1556 	ath_t *asc = arg;
1557 	struct ath_hal *ah = asc->asc_ah;
1558 
1559 	ATH_LOCK(asc);
1560 	ath_stop_locked(asc);
1561 	ATH_HAL_SETPOWER(ah, HAL_PM_AWAKE);
1562 	asc->asc_invalid = 1;
1563 	ATH_UNLOCK(asc);
1564 }
1565 
1566 int
1567 ath_m_start(void *arg)
1568 {
1569 	ath_t *asc = arg;
1570 	ieee80211com_t *ic = (ieee80211com_t *)asc;
1571 	struct ath_hal *ah = asc->asc_ah;
1572 	HAL_STATUS status;
1573 
1574 	ATH_LOCK(asc);
1575 	/*
1576 	 * Stop anything previously setup.  This is safe
1577 	 * whether this is the first time through or not.
1578 	 */
1579 	ath_stop_locked(asc);
1580 
1581 	/*
1582 	 * The basic interface to setting the hardware in a good
1583 	 * state is ``reset''.  On return the hardware is known to
1584 	 * be powered up and with interrupts disabled.  This must
1585 	 * be followed by initialization of the appropriate bits
1586 	 * and then setup of the interrupt mask.
1587 	 */
1588 	asc->asc_curchan.channel = ic->ic_curchan->ich_freq;
1589 	asc->asc_curchan.channelFlags = ath_chan2flags(ic, ic->ic_curchan);
1590 	if (!ATH_HAL_RESET(ah, (HAL_OPMODE)ic->ic_opmode,
1591 	    &asc->asc_curchan, AH_FALSE, &status)) {
1592 		ATH_DEBUG((ATH_DBG_HAL, "ath: ath_m_start(): "
1593 		    "reset hardware failed, hal status %u\n", status));
1594 		ATH_UNLOCK(asc);
1595 		return (ENOTACTIVE);
1596 	}
1597 
1598 	(void) ath_startrecv(asc);
1599 
1600 	/*
1601 	 * Enable interrupts.
1602 	 */
1603 	asc->asc_imask = HAL_INT_RX | HAL_INT_TX
1604 	    | HAL_INT_RXEOL | HAL_INT_RXORN
1605 	    | HAL_INT_FATAL | HAL_INT_GLOBAL;
1606 	ATH_HAL_INTRSET(ah, asc->asc_imask);
1607 
1608 	ic->ic_state = IEEE80211_S_INIT;
1609 
1610 	/*
1611 	 * The hardware should be ready to go now so it's safe
1612 	 * to kick the 802.11 state machine as it's likely to
1613 	 * immediately call back to us to send mgmt frames.
1614 	 */
1615 	ath_chan_change(asc, ic->ic_curchan);
1616 	asc->asc_invalid = 0;
1617 	ATH_UNLOCK(asc);
1618 	return (0);
1619 }
1620 
1621 
1622 static int
1623 ath_m_unicst(void *arg, const uint8_t *macaddr)
1624 {
1625 	ath_t *asc = arg;
1626 	struct ath_hal *ah = asc->asc_ah;
1627 
1628 	ATH_DEBUG((ATH_DBG_GLD, "ath: ath_gld_saddr(): "
1629 	    "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1630 	    macaddr[0], macaddr[1], macaddr[2],
1631 	    macaddr[3], macaddr[4], macaddr[5]));
1632 
1633 	ATH_LOCK(asc);
1634 	IEEE80211_ADDR_COPY(asc->asc_isc.ic_macaddr, macaddr);
1635 	ATH_HAL_SETMAC(ah, asc->asc_isc.ic_macaddr);
1636 
1637 	(void) ath_reset(&asc->asc_isc);
1638 	ATH_UNLOCK(asc);
1639 	return (0);
1640 }
1641 
1642 static int
1643 ath_m_promisc(void *arg, boolean_t on)
1644 {
1645 	ath_t *asc = arg;
1646 	struct ath_hal *ah = asc->asc_ah;
1647 	uint32_t rfilt;
1648 
1649 	ATH_LOCK(asc);
1650 	rfilt = ATH_HAL_GETRXFILTER(ah);
1651 	if (on)
1652 		rfilt |= HAL_RX_FILTER_PROM;
1653 	else
1654 		rfilt &= ~HAL_RX_FILTER_PROM;
1655 	ATH_HAL_SETRXFILTER(ah, rfilt);
1656 	ATH_UNLOCK(asc);
1657 
1658 	return (0);
1659 }
1660 
1661 static int
1662 ath_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
1663 {
1664 	ath_t *asc = arg;
1665 	struct ath_hal *ah = asc->asc_ah;
1666 	uint32_t mfilt[2], val, rfilt;
1667 	uint8_t pos;
1668 
1669 	ATH_LOCK(asc);
1670 	rfilt = ATH_HAL_GETRXFILTER(ah);
1671 
1672 	/* disable multicast */
1673 	if (!add) {
1674 		ATH_HAL_SETRXFILTER(ah, rfilt & (~HAL_RX_FILTER_MCAST));
1675 		ATH_UNLOCK(asc);
1676 		return (0);
1677 	}
1678 
1679 	/* enable multicast */
1680 	ATH_HAL_SETRXFILTER(ah, rfilt | HAL_RX_FILTER_MCAST);
1681 
1682 	mfilt[0] = mfilt[1] = 0;
1683 
1684 	/* calculate XOR of eight 6bit values */
1685 	val = ATH_LE_READ_4(mca + 0);
1686 	pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
1687 	val = ATH_LE_READ_4(mca + 3);
1688 	pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
1689 	pos &= 0x3f;
1690 	mfilt[pos / 32] |= (1 << (pos % 32));
1691 	ATH_HAL_SETMCASTFILTER(ah, mfilt[0], mfilt[1]);
1692 
1693 	ATH_UNLOCK(asc);
1694 	return (0);
1695 }
1696 
1697 static void
1698 ath_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
1699 {
1700 	ath_t *asc = arg;
1701 	int32_t err;
1702 
1703 	err = ieee80211_ioctl(&asc->asc_isc, wq, mp);
1704 	ATH_LOCK(asc);
1705 	if (err == ENETRESET) {
1706 		if (ATH_IS_RUNNING(asc)) {
1707 			ATH_UNLOCK(asc);
1708 			(void) ath_m_start(asc);
1709 			(void) ieee80211_new_state(&asc->asc_isc,
1710 			    IEEE80211_S_SCAN, -1);
1711 			ATH_LOCK(asc);
1712 		}
1713 	}
1714 	ATH_UNLOCK(asc);
1715 }
1716 
1717 static int
1718 ath_m_stat(void *arg, uint_t stat, uint64_t *val)
1719 {
1720 	ath_t *asc = arg;
1721 	ieee80211com_t *ic = (ieee80211com_t *)asc;
1722 	struct ieee80211_node *in = ic->ic_bss;
1723 	struct ieee80211_rateset *rs = &in->in_rates;
1724 
1725 	ATH_LOCK(asc);
1726 	switch (stat) {
1727 	case MAC_STAT_IFSPEED:
1728 		*val = (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2 *
1729 		    1000000ull;
1730 		break;
1731 	case MAC_STAT_NOXMTBUF:
1732 		*val = asc->asc_stats.ast_tx_nobuf +
1733 		    asc->asc_stats.ast_tx_nobufmgt;
1734 		break;
1735 	case MAC_STAT_IERRORS:
1736 		*val = asc->asc_stats.ast_rx_tooshort;
1737 		break;
1738 	case MAC_STAT_RBYTES:
1739 		*val = ic->ic_stats.is_rx_bytes;
1740 		break;
1741 	case MAC_STAT_IPACKETS:
1742 		*val = ic->ic_stats.is_rx_frags;
1743 		break;
1744 	case MAC_STAT_OBYTES:
1745 		*val = ic->ic_stats.is_tx_bytes;
1746 		break;
1747 	case MAC_STAT_OPACKETS:
1748 		*val = ic->ic_stats.is_tx_frags;
1749 		break;
1750 	case MAC_STAT_OERRORS:
1751 	case WIFI_STAT_TX_FAILED:
1752 		*val = asc->asc_stats.ast_tx_fifoerr +
1753 		    asc->asc_stats.ast_tx_xretries +
1754 		    asc->asc_stats.ast_tx_discard;
1755 		break;
1756 	case WIFI_STAT_TX_RETRANS:
1757 		*val = asc->asc_stats.ast_tx_xretries;
1758 		break;
1759 	case WIFI_STAT_FCS_ERRORS:
1760 		*val = asc->asc_stats.ast_rx_crcerr;
1761 		break;
1762 	case WIFI_STAT_WEP_ERRORS:
1763 		*val = asc->asc_stats.ast_rx_badcrypt;
1764 		break;
1765 	case WIFI_STAT_TX_FRAGS:
1766 	case WIFI_STAT_MCAST_TX:
1767 	case WIFI_STAT_RTS_SUCCESS:
1768 	case WIFI_STAT_RTS_FAILURE:
1769 	case WIFI_STAT_ACK_FAILURE:
1770 	case WIFI_STAT_RX_FRAGS:
1771 	case WIFI_STAT_MCAST_RX:
1772 	case WIFI_STAT_RX_DUPS:
1773 		ATH_UNLOCK(asc);
1774 		return (ieee80211_stat(ic, stat, val));
1775 	default:
1776 		ATH_UNLOCK(asc);
1777 		return (ENOTSUP);
1778 	}
1779 	ATH_UNLOCK(asc);
1780 
1781 	return (0);
1782 }
1783 
1784 static int
1785 ath_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
1786 {
1787 	ath_t *asc;
1788 	ieee80211com_t *ic;
1789 	struct ath_hal *ah;
1790 	uint8_t csz;
1791 	HAL_STATUS status;
1792 	caddr_t regs;
1793 	uint32_t i, val;
1794 	uint16_t vendor_id, device_id, command;
1795 	const char *athname;
1796 	int32_t ath_countrycode = CTRY_DEFAULT;	/* country code */
1797 	int32_t err, ath_regdomain = 0; /* regulatory domain */
1798 	char strbuf[32];
1799 	int instance;
1800 	wifi_data_t wd = { 0 };
1801 	mac_register_t *macp;
1802 
1803 	if (cmd != DDI_ATTACH)
1804 		return (DDI_FAILURE);
1805 
1806 	instance = ddi_get_instance(devinfo);
1807 	if (ddi_soft_state_zalloc(ath_soft_state_p, instance) != DDI_SUCCESS) {
1808 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1809 		    "Unable to alloc softstate\n"));
1810 		return (DDI_FAILURE);
1811 	}
1812 
1813 	asc = ddi_get_soft_state(ath_soft_state_p, ddi_get_instance(devinfo));
1814 	ic = (ieee80211com_t *)asc;
1815 	asc->asc_dev = devinfo;
1816 
1817 	mutex_init(&asc->asc_genlock, NULL, MUTEX_DRIVER, NULL);
1818 	mutex_init(&asc->asc_txbuflock, NULL, MUTEX_DRIVER, NULL);
1819 	mutex_init(&asc->asc_rxbuflock, NULL, MUTEX_DRIVER, NULL);
1820 	mutex_init(&asc->asc_resched_lock, NULL, MUTEX_DRIVER, NULL);
1821 
1822 	err = pci_config_setup(devinfo, &asc->asc_cfg_handle);
1823 	if (err != DDI_SUCCESS) {
1824 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1825 		    "pci_config_setup() failed"));
1826 		goto attach_fail0;
1827 	}
1828 
1829 	csz = pci_config_get8(asc->asc_cfg_handle, PCI_CONF_CACHE_LINESZ);
1830 	asc->asc_cachelsz = csz << 2;
1831 	vendor_id = pci_config_get16(asc->asc_cfg_handle, PCI_CONF_VENID);
1832 	device_id = pci_config_get16(asc->asc_cfg_handle, PCI_CONF_DEVID);
1833 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): vendor 0x%x, "
1834 	    "device id 0x%x, cache size %d\n", vendor_id, device_id, csz));
1835 
1836 	athname = ath_hal_probe(vendor_id, device_id);
1837 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): athname: %s\n",
1838 	    athname ? athname : "Atheros ???"));
1839 
1840 	/*
1841 	 * Enable response to memory space accesses,
1842 	 * and enabe bus master.
1843 	 */
1844 	command = PCI_COMM_MAE | PCI_COMM_ME;
1845 	pci_config_put16(asc->asc_cfg_handle, PCI_CONF_COMM, command);
1846 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1847 	    "set command reg to 0x%x \n", command));
1848 
1849 	pci_config_put8(asc->asc_cfg_handle, PCI_CONF_LATENCY_TIMER, 0xa8);
1850 	val = pci_config_get32(asc->asc_cfg_handle, 0x40);
1851 	if ((val & 0x0000ff00) != 0)
1852 		pci_config_put32(asc->asc_cfg_handle, 0x40, val & 0xffff00ff);
1853 
1854 	err = ddi_regs_map_setup(devinfo, 1,
1855 	    &regs, 0, 0, &ath_reg_accattr, &asc->asc_io_handle);
1856 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1857 	    "regs map1 = %x err=%d\n", regs, err));
1858 	if (err != DDI_SUCCESS) {
1859 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1860 		    "ddi_regs_map_setup() failed"));
1861 		goto attach_fail1;
1862 	}
1863 
1864 	ah = ath_hal_attach(device_id, asc, 0, regs, &status);
1865 	if (ah == NULL) {
1866 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1867 		    "unable to attach hw; HAL status %u\n", status));
1868 		goto attach_fail2;
1869 	}
1870 	ATH_HAL_INTRSET(ah, 0);
1871 	asc->asc_ah = ah;
1872 
1873 	if (ah->ah_abi != HAL_ABI_VERSION) {
1874 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1875 		    "HAL ABI mismatch detected (0x%x != 0x%x)\n",
1876 		    ah->ah_abi, HAL_ABI_VERSION));
1877 		goto attach_fail3;
1878 	}
1879 
1880 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1881 	    "HAL ABI version 0x%x\n", ah->ah_abi));
1882 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1883 	    "HAL mac version %d.%d, phy version %d.%d\n",
1884 	    ah->ah_macVersion, ah->ah_macRev,
1885 	    ah->ah_phyRev >> 4, ah->ah_phyRev & 0xf));
1886 	if (ah->ah_analog5GhzRev)
1887 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1888 		    "HAL 5ghz radio version %d.%d\n",
1889 		    ah->ah_analog5GhzRev >> 4,
1890 		    ah->ah_analog5GhzRev & 0xf));
1891 	if (ah->ah_analog2GhzRev)
1892 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1893 		    "HAL 2ghz radio version %d.%d\n",
1894 		    ah->ah_analog2GhzRev >> 4,
1895 		    ah->ah_analog2GhzRev & 0xf));
1896 
1897 	/*
1898 	 * Check if the MAC has multi-rate retry support.
1899 	 * We do this by trying to setup a fake extended
1900 	 * descriptor.  MAC's that don't have support will
1901 	 * return false w/o doing anything.  MAC's that do
1902 	 * support it will return true w/o doing anything.
1903 	 */
1904 	asc->asc_mrretry = ATH_HAL_SETUPXTXDESC(ah, NULL, 0, 0, 0, 0, 0, 0);
1905 	ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1906 	    "multi rate retry support=%x\n",
1907 	    asc->asc_mrretry));
1908 
1909 	/*
1910 	 * Get the hardware key cache size.
1911 	 */
1912 	asc->asc_keymax = ATH_HAL_KEYCACHESIZE(ah);
1913 	if (asc->asc_keymax > sizeof (asc->asc_keymap) * NBBY) {
1914 		ATH_DEBUG((ATH_DBG_ATTACH, "ath_attach:"
1915 		    " Warning, using only %u entries in %u key cache\n",
1916 		    sizeof (asc->asc_keymap) * NBBY, asc->asc_keymax));
1917 		asc->asc_keymax = sizeof (asc->asc_keymap) * NBBY;
1918 	}
1919 	/*
1920 	 * Reset the key cache since some parts do not
1921 	 * reset the contents on initial power up.
1922 	 */
1923 	for (i = 0; i < asc->asc_keymax; i++)
1924 		ATH_HAL_KEYRESET(ah, i);
1925 
1926 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1927 		setbit(asc->asc_keymap, i);
1928 		setbit(asc->asc_keymap, i+32);
1929 		setbit(asc->asc_keymap, i+64);
1930 		setbit(asc->asc_keymap, i+32+64);
1931 	}
1932 
1933 	ATH_HAL_GETREGDOMAIN(ah, (uint32_t *)&ath_regdomain);
1934 	ATH_HAL_GETCOUNTRYCODE(ah, &ath_countrycode);
1935 	/*
1936 	 * Collect the channel list using the default country
1937 	 * code and including outdoor channels.  The 802.11 layer
1938 	 * is resposible for filtering this list to a set of
1939 	 * channels that it considers ok to use.
1940 	 */
1941 	asc->asc_have11g = 0;
1942 
1943 	/* enable outdoor use, enable extended channels */
1944 	err = ath_getchannels(asc, ath_countrycode, AH_FALSE, AH_TRUE);
1945 	if (err != 0)
1946 		goto attach_fail3;
1947 
1948 	/*
1949 	 * Setup rate tables for all potential media types.
1950 	 */
1951 	ath_rate_setup(asc, IEEE80211_MODE_11A);
1952 	ath_rate_setup(asc, IEEE80211_MODE_11B);
1953 	ath_rate_setup(asc, IEEE80211_MODE_11G);
1954 	ath_rate_setup(asc, IEEE80211_MODE_TURBO_A);
1955 
1956 	/* Setup here so ath_rate_update is happy */
1957 	ath_setcurmode(asc, IEEE80211_MODE_11A);
1958 
1959 	err = ath_desc_alloc(devinfo, asc);
1960 	if (err != DDI_SUCCESS) {
1961 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
1962 		    "failed to allocate descriptors: %d\n", err));
1963 		goto attach_fail3;
1964 	}
1965 
1966 	/* Setup transmit queues in the HAL */
1967 	if (ath_txq_setup(asc))
1968 		goto attach_fail4;
1969 
1970 	ATH_HAL_GETMAC(ah, ic->ic_macaddr);
1971 
1972 	/*
1973 	 * Initialize pointers to device specific functions which
1974 	 * will be used by the generic layer.
1975 	 */
1976 	/* 11g support is identified when we fetch the channel set */
1977 	if (asc->asc_have11g)
1978 		ic->ic_caps |= IEEE80211_C_SHPREAMBLE |
1979 		    IEEE80211_C_SHSLOT;		/* short slot time */
1980 	/*
1981 	 * Query the hal to figure out h/w crypto support.
1982 	 */
1983 	if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_WEP))
1984 		ic->ic_caps |= IEEE80211_C_WEP;
1985 	if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_AES_OCB))
1986 		ic->ic_caps |= IEEE80211_C_AES;
1987 	if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_AES_CCM)) {
1988 		ATH_DEBUG((ATH_DBG_ATTACH, "Atheros support H/W CCMP\n"));
1989 		ic->ic_caps |= IEEE80211_C_AES_CCM;
1990 	}
1991 	if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_CKIP))
1992 		ic->ic_caps |= IEEE80211_C_CKIP;
1993 	if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_TKIP)) {
1994 		ATH_DEBUG((ATH_DBG_ATTACH, "Atheros support H/W TKIP\n"));
1995 		ic->ic_caps |= IEEE80211_C_TKIP;
1996 		/*
1997 		 * Check if h/w does the MIC and/or whether the
1998 		 * separate key cache entries are required to
1999 		 * handle both tx+rx MIC keys.
2000 		 */
2001 		if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_MIC)) {
2002 			ATH_DEBUG((ATH_DBG_ATTACH, "Support H/W TKIP MIC\n"));
2003 			ic->ic_caps |= IEEE80211_C_TKIPMIC;
2004 		}
2005 		if (ATH_HAL_TKIPSPLIT(ah))
2006 			asc->asc_splitmic = 1;
2007 	}
2008 	ic->ic_caps |= IEEE80211_C_WPA;	/* Support WPA/WPA2 */
2009 
2010 	asc->asc_hasclrkey = ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_CLR);
2011 	ic->ic_phytype = IEEE80211_T_OFDM;
2012 	ic->ic_opmode = IEEE80211_M_STA;
2013 	ic->ic_state = IEEE80211_S_INIT;
2014 	ic->ic_maxrssi = ATH_MAX_RSSI;
2015 	ic->ic_set_shortslot = ath_set_shortslot;
2016 	ic->ic_xmit = ath_xmit;
2017 	ieee80211_attach(ic);
2018 
2019 	/* different instance has different WPA door */
2020 	(void) snprintf(ic->ic_wpadoor, MAX_IEEE80211STR, "%s_%s%d", WPA_DOOR,
2021 		ddi_driver_name(devinfo),
2022 		ddi_get_instance(devinfo));
2023 
2024 	/* Override 80211 default routines */
2025 	ic->ic_reset = ath_reset;
2026 	asc->asc_newstate = ic->ic_newstate;
2027 	ic->ic_newstate = ath_newstate;
2028 	ic->ic_watchdog = ath_watchdog;
2029 	ic->ic_node_alloc = ath_node_alloc;
2030 	ic->ic_node_free = ath_node_free;
2031 	ic->ic_crypto.cs_key_alloc = ath_key_alloc;
2032 	ic->ic_crypto.cs_key_delete = ath_key_delete;
2033 	ic->ic_crypto.cs_key_set = ath_key_set;
2034 	ieee80211_media_init(ic);
2035 	/*
2036 	 * initialize default tx key
2037 	 */
2038 	ic->ic_def_txkey = 0;
2039 
2040 	asc->asc_rx_pend = 0;
2041 	ATH_HAL_INTRSET(ah, 0);
2042 	err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW,
2043 	    &asc->asc_softint_id, NULL, 0, ath_softint_handler, (caddr_t)asc);
2044 	if (err != DDI_SUCCESS) {
2045 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2046 		    "ddi_add_softintr() failed\n"));
2047 		goto attach_fail5;
2048 	}
2049 
2050 	if (ddi_get_iblock_cookie(devinfo, 0, &asc->asc_iblock)
2051 	    != DDI_SUCCESS) {
2052 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2053 		    "Can not get iblock cookie for INT\n"));
2054 		goto attach_fail6;
2055 	}
2056 
2057 	if (ddi_add_intr(devinfo, 0, NULL, NULL, ath_intr,
2058 	    (caddr_t)asc) != DDI_SUCCESS) {
2059 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2060 		    "Can not set intr for ATH driver\n"));
2061 		goto attach_fail6;
2062 	}
2063 
2064 	/*
2065 	 * Provide initial settings for the WiFi plugin; whenever this
2066 	 * information changes, we need to call mac_plugindata_update()
2067 	 */
2068 	wd.wd_opmode = ic->ic_opmode;
2069 	wd.wd_secalloc = WIFI_SEC_NONE;
2070 	IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
2071 
2072 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
2073 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2074 		    "MAC version mismatch\n"));
2075 		goto attach_fail7;
2076 	}
2077 
2078 	macp->m_type_ident	= MAC_PLUGIN_IDENT_WIFI;
2079 	macp->m_driver		= asc;
2080 	macp->m_dip		= devinfo;
2081 	macp->m_src_addr	= ic->ic_macaddr;
2082 	macp->m_callbacks	= &ath_m_callbacks;
2083 	macp->m_min_sdu		= 0;
2084 	macp->m_max_sdu		= IEEE80211_MTU;
2085 	macp->m_pdata		= &wd;
2086 	macp->m_pdata_size	= sizeof (wd);
2087 
2088 	err = mac_register(macp, &ic->ic_mach);
2089 	mac_free(macp);
2090 	if (err != 0) {
2091 		ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2092 		    "mac_register err %x\n", err));
2093 		goto attach_fail7;
2094 	}
2095 
2096 	/* Create minor node of type DDI_NT_NET_WIFI */
2097 	(void) snprintf(strbuf, sizeof (strbuf), "%s%d",
2098 	    ATH_NODENAME, instance);
2099 	err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
2100 	    instance + 1, DDI_NT_NET_WIFI, 0);
2101 	if (err != DDI_SUCCESS)
2102 		ATH_DEBUG((ATH_DBG_ATTACH, "WARN: ath: ath_attach(): "
2103 		    "Create minor node failed - %d\n", err));
2104 
2105 	mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
2106 	asc->asc_invalid = 1;
2107 	return (DDI_SUCCESS);
2108 attach_fail7:
2109 	ddi_remove_intr(devinfo, 0, asc->asc_iblock);
2110 attach_fail6:
2111 	ddi_remove_softintr(asc->asc_softint_id);
2112 attach_fail5:
2113 	(void) ieee80211_detach(ic);
2114 attach_fail4:
2115 	ath_desc_free(asc);
2116 attach_fail3:
2117 	ah->ah_detach(asc->asc_ah);
2118 attach_fail2:
2119 	ddi_regs_map_free(&asc->asc_io_handle);
2120 attach_fail1:
2121 	pci_config_teardown(&asc->asc_cfg_handle);
2122 attach_fail0:
2123 	asc->asc_invalid = 1;
2124 	mutex_destroy(&asc->asc_txbuflock);
2125 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
2126 		if (ATH_TXQ_SETUP(asc, i)) {
2127 			struct ath_txq *txq = &asc->asc_txq[i];
2128 			mutex_destroy(&txq->axq_lock);
2129 		}
2130 	}
2131 	mutex_destroy(&asc->asc_rxbuflock);
2132 	mutex_destroy(&asc->asc_genlock);
2133 	mutex_destroy(&asc->asc_resched_lock);
2134 	ddi_soft_state_free(ath_soft_state_p, instance);
2135 
2136 	return (DDI_FAILURE);
2137 }
2138 
2139 static int32_t
2140 ath_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
2141 {
2142 	ath_t *asc;
2143 
2144 	asc = ddi_get_soft_state(ath_soft_state_p, ddi_get_instance(devinfo));
2145 	ASSERT(asc != NULL);
2146 
2147 	if (cmd != DDI_DETACH)
2148 		return (DDI_FAILURE);
2149 
2150 	ath_stop_scantimer(asc);
2151 
2152 	/* disable interrupts */
2153 	ATH_HAL_INTRSET(asc->asc_ah, 0);
2154 
2155 	/*
2156 	 * Unregister from the MAC layer subsystem
2157 	 */
2158 	if (mac_unregister(asc->asc_isc.ic_mach) != 0)
2159 		return (DDI_FAILURE);
2160 
2161 	/* free intterrupt resources */
2162 	ddi_remove_intr(devinfo, 0, asc->asc_iblock);
2163 	ddi_remove_softintr(asc->asc_softint_id);
2164 
2165 	/*
2166 	 * NB: the order of these is important:
2167 	 * o call the 802.11 layer before detaching the hal to
2168 	 *   insure callbacks into the driver to delete global
2169 	 *   key cache entries can be handled
2170 	 * o reclaim the tx queue data structures after calling
2171 	 *   the 802.11 layer as we'll get called back to reclaim
2172 	 *   node state and potentially want to use them
2173 	 * o to cleanup the tx queues the hal is called, so detach
2174 	 *   it last
2175 	 */
2176 	ieee80211_detach(&asc->asc_isc);
2177 	ath_desc_free(asc);
2178 	ath_txq_cleanup(asc);
2179 	asc->asc_ah->ah_detach(asc->asc_ah);
2180 
2181 	/* free io handle */
2182 	ddi_regs_map_free(&asc->asc_io_handle);
2183 	pci_config_teardown(&asc->asc_cfg_handle);
2184 
2185 	/* destroy locks */
2186 	mutex_destroy(&asc->asc_rxbuflock);
2187 	mutex_destroy(&asc->asc_genlock);
2188 	mutex_destroy(&asc->asc_resched_lock);
2189 
2190 	ddi_remove_minor_node(devinfo, NULL);
2191 	ddi_soft_state_free(ath_soft_state_p, ddi_get_instance(devinfo));
2192 
2193 	return (DDI_SUCCESS);
2194 }
2195 
2196 DDI_DEFINE_STREAM_OPS(ath_dev_ops, nulldev, nulldev, ath_attach, ath_detach,
2197     nodev, NULL, D_MP, NULL);
2198 
2199 static struct modldrv ath_modldrv = {
2200 	&mod_driverops,		/* Type of module.  This one is a driver */
2201 	"ath driver 1.3/HAL 0.9.17.2",	/* short description */
2202 	&ath_dev_ops		/* driver specific ops */
2203 };
2204 
2205 static struct modlinkage modlinkage = {
2206 	MODREV_1, (void *)&ath_modldrv, NULL
2207 };
2208 
2209 
2210 int
2211 _info(struct modinfo *modinfop)
2212 {
2213 	return (mod_info(&modlinkage, modinfop));
2214 }
2215 
2216 int
2217 _init(void)
2218 {
2219 	int status;
2220 
2221 	status = ddi_soft_state_init(&ath_soft_state_p, sizeof (ath_t), 1);
2222 	if (status != 0)
2223 		return (status);
2224 
2225 	mutex_init(&ath_loglock, NULL, MUTEX_DRIVER, NULL);
2226 	ath_halfix_init();
2227 	mac_init_ops(&ath_dev_ops, "ath");
2228 	status = mod_install(&modlinkage);
2229 	if (status != 0) {
2230 		mac_fini_ops(&ath_dev_ops);
2231 		ath_halfix_finit();
2232 		mutex_destroy(&ath_loglock);
2233 		ddi_soft_state_fini(&ath_soft_state_p);
2234 	}
2235 
2236 	return (status);
2237 }
2238 
2239 int
2240 _fini(void)
2241 {
2242 	int status;
2243 
2244 	status = mod_remove(&modlinkage);
2245 	if (status == 0) {
2246 		mac_fini_ops(&ath_dev_ops);
2247 		ath_halfix_finit();
2248 		mutex_destroy(&ath_loglock);
2249 		ddi_soft_state_fini(&ath_soft_state_p);
2250 	}
2251 	return (status);
2252 }
2253