Merge commit '37e84ab74e939caf52150fc3352081786ecc0c29' into merges
[unleashed.git] / kernel / drivers / net / wifi / ath / ath_main.c
blob83ef45be0102c9cd16cfb66ad677089b3cb2eeea
1 /*
2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 * Copyright 2016 PALO, Richard.
5 */
7 /*
8 * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
19 * redistribution must be conditioned upon including a substantially
20 * similar Disclaimer requirement for further binary redistribution.
21 * 3. Neither the names of the above-listed copyright holders nor the names
22 * of any contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * NO WARRANTY
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
30 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
31 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGES.
41 * Driver for the Atheros Wireless LAN controller.
43 * The Atheros driver calls into net80211 module for IEEE80211 protocol
44 * management functionalities. The driver includes a LLD(Low Level Driver)
45 * part to implement H/W related operations.
46 * The following is the high level structure of ath driver.
47 * (The arrows between modules indicate function call direction.)
50 * |
51 * | GLD thread
52 * V
53 * ================== =========================================
54 * | | |[1] |
55 * | | | GLDv3 Callback functions registered |
56 * | Net80211 | ========================= by |
57 * | module | | | driver |
58 * | | V | |
59 * | |======================== | |
60 * | Functions exported by net80211 | | |
61 * | | | |
62 * ========================================== =================
63 * | |
64 * V |
65 * +----------------------------------+ |
66 * |[2] | |
67 * | Net80211 Callback functions | |
68 * | registered by LLD | |
69 * +----------------------------------+ |
70 * | |
71 * V v
72 * +-----------------------------------------------------------+
73 * |[3] |
74 * | LLD Internal functions |
75 * | |
76 * +-----------------------------------------------------------+
77 * ^
78 * | Software interrupt thread
79 * |
81 * The short description of each module is as below:
82 * Module 1: GLD callback functions, which are intercepting the calls from
83 * GLD to LLD.
84 * Module 2: Net80211 callback functions registered by LLD, which
85 * calls into LLD for H/W related functions needed by net80211.
86 * Module 3: LLD Internal functions, which are responsible for allocing
87 * descriptor/buffer, handling interrupt and other H/W
88 * operations.
90 * All functions are running in 3 types of thread:
91 * 1. GLD callbacks threads, such as ioctl, intr, etc.
92 * 2. Clock interruptt thread which is responsible for scan, rate control and
93 * calibration.
94 * 3. Software Interrupt thread originated in LLD.
96 * The lock strategy is as below:
97 * There have 4 queues for tx, each queue has one asc_txqlock[i] to
98 * prevent conflicts access to queue resource from different thread.
100 * All the transmit buffers are contained in asc_txbuf which are
101 * protected by asc_txbuflock.
103 * Each receive buffers are contained in asc_rxbuf which are protected
104 * by asc_rxbuflock.
106 * In ath struct, asc_genlock is a general lock, protecting most other
107 * operational data in ath_softc struct and HAL accesses.
108 * It is acquired by the interupt handler and most "mode-ctrl" routines.
110 * Any of the locks can be acquired singly, but where multiple
111 * locks are acquired, they *must* be in the order:
112 * asc_genlock >> asc_txqlock[i] >> asc_txbuflock >> asc_rxbuflock
115 #include <sys/param.h>
116 #include <sys/types.h>
117 #include <sys/signal.h>
118 #include <sys/stream.h>
119 #include <sys/termio.h>
120 #include <sys/errno.h>
121 #include <sys/file.h>
122 #include <sys/cmn_err.h>
123 #include <sys/stropts.h>
124 #include <sys/strsubr.h>
125 #include <sys/strtty.h>
126 #include <sys/kbio.h>
127 #include <sys/cred.h>
128 #include <sys/stat.h>
129 #include <sys/consdev.h>
130 #include <sys/kmem.h>
131 #include <sys/modctl.h>
132 #include <sys/ddi.h>
133 #include <sys/sunddi.h>
134 #include <sys/pci.h>
135 #include <sys/errno.h>
136 #include <sys/mac_provider.h>
137 #include <sys/dlpi.h>
138 #include <sys/ethernet.h>
139 #include <sys/list.h>
140 #include <sys/byteorder.h>
141 #include <sys/strsun.h>
142 #include <sys/policy.h>
143 #include <inet/common.h>
144 #include <inet/nd.h>
145 #include <inet/mi.h>
146 #include <inet/wifi_ioctl.h>
147 #include <sys/mac_wifi.h>
148 #include "ath_hal.h"
149 #include "ath_impl.h"
150 #include "ath_aux.h"
151 #include "ath_rate.h"
153 #define ATH_MAX_RSSI 63 /* max rssi */
155 extern void ath_halfix_init(void);
156 extern void ath_halfix_finit(void);
157 extern int32_t ath_getset(ath_t *asc, mblk_t *mp, uint32_t cmd);
160 * PIO access attributes for registers
162 static ddi_device_acc_attr_t ath_reg_accattr = {
163 DDI_DEVICE_ATTR_V0,
164 DDI_STRUCTURE_LE_ACC,
165 DDI_STRICTORDER_ACC
169 * DMA access attributes for descriptors: NOT to be byte swapped.
171 static ddi_device_acc_attr_t ath_desc_accattr = {
172 DDI_DEVICE_ATTR_V0,
173 DDI_STRUCTURE_LE_ACC,
174 DDI_STRICTORDER_ACC
178 * DMA attributes for rx/tx buffers
180 static ddi_dma_attr_t ath_dma_attr = {
181 DMA_ATTR_V0, /* version number */
182 0, /* low address */
183 0xffffffffU, /* high address */
184 0x3ffffU, /* counter register max */
185 1, /* alignment */
186 0xFFF, /* burst sizes */
187 1, /* minimum transfer size */
188 0x3ffffU, /* max transfer size */
189 0xffffffffU, /* address register max */
190 1, /* no scatter-gather */
191 1, /* granularity of device */
192 0, /* DMA flags */
195 static ddi_dma_attr_t ath_desc_dma_attr = {
196 DMA_ATTR_V0, /* version number */
197 0, /* low address */
198 0xffffffffU, /* high address */
199 0xffffffffU, /* counter register max */
200 0x1000, /* alignment */
201 0xFFF, /* burst sizes */
202 1, /* minimum transfer size */
203 0xffffffffU, /* max transfer size */
204 0xffffffffU, /* address register max */
205 1, /* no scatter-gather */
206 1, /* granularity of device */
207 0, /* DMA flags */
210 static kmutex_t ath_loglock;
211 static void *ath_soft_state_p = NULL;
212 static int ath_dwelltime = 150; /* scan interval, ms */
214 static int ath_m_stat(void *, uint_t, uint64_t *);
215 static int ath_m_start(void *);
216 static void ath_m_stop(void *);
217 static int ath_m_promisc(void *, boolean_t);
218 static int ath_m_multicst(void *, boolean_t, const uint8_t *);
219 static int ath_m_unicst(void *, const uint8_t *);
220 static mblk_t *ath_m_tx(void *, mblk_t *);
221 static void ath_m_ioctl(void *, queue_t *, mblk_t *);
222 static int ath_m_setprop(void *, const char *, mac_prop_id_t,
223 uint_t, const void *);
224 static int ath_m_getprop(void *, const char *, mac_prop_id_t,
225 uint_t, void *);
226 static void ath_m_propinfo(void *, const char *, mac_prop_id_t,
227 mac_prop_info_handle_t);
229 static mac_callbacks_t ath_m_callbacks = {
230 MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
231 ath_m_stat,
232 ath_m_start,
233 ath_m_stop,
234 ath_m_promisc,
235 ath_m_multicst,
236 ath_m_unicst,
237 ath_m_tx,
238 NULL,
239 ath_m_ioctl,
240 NULL, /* mc_getcapab */
241 NULL,
242 NULL,
243 ath_m_setprop,
244 ath_m_getprop,
245 ath_m_propinfo
249 * Available debug flags:
250 * ATH_DBG_INIT, ATH_DBG_GLD, ATH_DBG_HAL, ATH_DBG_INT, ATH_DBG_ATTACH,
251 * ATH_DBG_DETACH, ATH_DBG_AUX, ATH_DBG_WIFICFG, ATH_DBG_OSDEP
253 uint32_t ath_dbg_flags = 0;
256 * Exception/warning cases not leading to panic.
258 void
259 ath_problem(const int8_t *fmt, ...)
261 va_list args;
263 mutex_enter(&ath_loglock);
265 va_start(args, fmt);
266 vcmn_err(CE_WARN, fmt, args);
267 va_end(args);
269 mutex_exit(&ath_loglock);
273 * Normal log information independent of debug.
275 void
276 ath_log(const int8_t *fmt, ...)
278 va_list args;
280 mutex_enter(&ath_loglock);
282 va_start(args, fmt);
283 vcmn_err(CE_CONT, fmt, args);
284 va_end(args);
286 mutex_exit(&ath_loglock);
289 void
290 ath_dbg(uint32_t dbg_flags, const int8_t *fmt, ...)
292 va_list args;
294 if (dbg_flags & ath_dbg_flags) {
295 mutex_enter(&ath_loglock);
296 va_start(args, fmt);
297 vcmn_err(CE_CONT, fmt, args);
298 va_end(args);
299 mutex_exit(&ath_loglock);
303 void
304 ath_setup_desc(ath_t *asc, struct ath_buf *bf)
306 struct ath_desc *ds;
308 ds = bf->bf_desc;
309 ds->ds_link = bf->bf_daddr;
310 ds->ds_data = bf->bf_dma.cookie.dmac_address;
311 ATH_HAL_SETUPRXDESC(asc->asc_ah, ds,
312 bf->bf_dma.alength, /* buffer size */
315 if (asc->asc_rxlink != NULL)
316 *asc->asc_rxlink = bf->bf_daddr;
317 asc->asc_rxlink = &ds->ds_link;
322 * Allocate an area of memory and a DMA handle for accessing it
324 static int
325 ath_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr, size_t memsize,
326 ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
327 uint_t bind_flags, dma_area_t *dma_p)
329 int err;
332 * Allocate handle
334 err = ddi_dma_alloc_handle(devinfo, dma_attr,
335 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
336 if (err != DDI_SUCCESS)
337 return (DDI_FAILURE);
340 * Allocate memory
342 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
343 alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
344 &dma_p->alength, &dma_p->acc_hdl);
345 if (err != DDI_SUCCESS)
346 return (DDI_FAILURE);
349 * Bind the two together
351 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
352 dma_p->mem_va, dma_p->alength, bind_flags,
353 DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
354 if (err != DDI_DMA_MAPPED)
355 return (DDI_FAILURE);
357 dma_p->nslots = ~0U;
358 dma_p->size = ~0U;
359 dma_p->token = ~0U;
360 dma_p->offset = 0;
361 return (DDI_SUCCESS);
365 * Free one allocated area of DMAable memory
367 static void
368 ath_free_dma_mem(dma_area_t *dma_p)
370 if (dma_p->dma_hdl != NULL) {
371 (void) ddi_dma_unbind_handle(dma_p->dma_hdl);
372 if (dma_p->acc_hdl != NULL) {
373 ddi_dma_mem_free(&dma_p->acc_hdl);
374 dma_p->acc_hdl = NULL;
376 ddi_dma_free_handle(&dma_p->dma_hdl);
377 dma_p->ncookies = 0;
378 dma_p->dma_hdl = NULL;
384 * Initialize tx/rx buffer list. Allocate DMA memory for
385 * each buffer.
387 static int
388 ath_buflist_setup(dev_info_t *devinfo, ath_t *asc, list_t *bflist,
389 struct ath_buf **pbf, struct ath_desc **pds, int nbuf, uint_t dmabflags)
391 int i, err;
392 struct ath_buf *bf = *pbf;
393 struct ath_desc *ds = *pds;
395 list_create(bflist, sizeof (struct ath_buf),
396 offsetof(struct ath_buf, bf_node));
397 for (i = 0; i < nbuf; i++, bf++, ds++) {
398 bf->bf_desc = ds;
399 bf->bf_daddr = asc->asc_desc_dma.cookie.dmac_address +
400 ((uintptr_t)ds - (uintptr_t)asc->asc_desc);
401 list_insert_tail(bflist, bf);
403 /* alloc DMA memory */
404 err = ath_alloc_dma_mem(devinfo, &ath_dma_attr,
405 asc->asc_dmabuf_size, &ath_desc_accattr, DDI_DMA_STREAMING,
406 dmabflags, &bf->bf_dma);
407 if (err != DDI_SUCCESS)
408 return (err);
410 *pbf = bf;
411 *pds = ds;
413 return (DDI_SUCCESS);
417 * Destroy tx/rx buffer list. Free DMA memory.
419 static void
420 ath_buflist_cleanup(list_t *buflist)
422 struct ath_buf *bf;
424 if (!buflist)
425 return;
427 bf = list_head(buflist);
428 while (bf != NULL) {
429 if (bf->bf_m != NULL) {
430 freemsg(bf->bf_m);
431 bf->bf_m = NULL;
433 /* Free DMA buffer */
434 ath_free_dma_mem(&bf->bf_dma);
435 if (bf->bf_in != NULL) {
436 ieee80211_free_node(bf->bf_in);
437 bf->bf_in = NULL;
439 list_remove(buflist, bf);
440 bf = list_head(buflist);
442 list_destroy(buflist);
446 static void
447 ath_desc_free(ath_t *asc)
449 ath_buflist_cleanup(&asc->asc_txbuf_list);
450 ath_buflist_cleanup(&asc->asc_rxbuf_list);
452 /* Free descriptor DMA buffer */
453 ath_free_dma_mem(&asc->asc_desc_dma);
455 kmem_free((void *)asc->asc_vbufptr, asc->asc_vbuflen);
456 asc->asc_vbufptr = NULL;
459 static int
460 ath_desc_alloc(dev_info_t *devinfo, ath_t *asc)
462 int err;
463 size_t size;
464 struct ath_desc *ds;
465 struct ath_buf *bf;
467 size = sizeof (struct ath_desc) * (ATH_TXBUF + ATH_RXBUF);
469 err = ath_alloc_dma_mem(devinfo, &ath_desc_dma_attr, size,
470 &ath_desc_accattr, DDI_DMA_CONSISTENT,
471 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &asc->asc_desc_dma);
473 /* virtual address of the first descriptor */
474 asc->asc_desc = (struct ath_desc *)asc->asc_desc_dma.mem_va;
476 ds = asc->asc_desc;
477 ATH_DEBUG((ATH_DBG_INIT, "ath: ath_desc_alloc(): DMA map: "
478 "%p (%d) -> %p\n",
479 asc->asc_desc, asc->asc_desc_dma.alength,
480 asc->asc_desc_dma.cookie.dmac_address));
482 /* allocate data structures to describe TX/RX DMA buffers */
483 asc->asc_vbuflen = sizeof (struct ath_buf) * (ATH_TXBUF + ATH_RXBUF);
484 bf = kmem_zalloc(asc->asc_vbuflen, KM_SLEEP);
485 asc->asc_vbufptr = bf;
487 /* DMA buffer size for each TX/RX packet */
488 asc->asc_dmabuf_size = roundup(1000 + sizeof (struct ieee80211_frame) +
489 IEEE80211_MTU + IEEE80211_CRC_LEN +
490 (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
491 IEEE80211_WEP_CRCLEN), asc->asc_cachelsz);
493 /* create RX buffer list */
494 err = ath_buflist_setup(devinfo, asc, &asc->asc_rxbuf_list, &bf, &ds,
495 ATH_RXBUF, DDI_DMA_READ | DDI_DMA_STREAMING);
496 if (err != DDI_SUCCESS) {
497 ath_desc_free(asc);
498 return (err);
501 /* create TX buffer list */
502 err = ath_buflist_setup(devinfo, asc, &asc->asc_txbuf_list, &bf, &ds,
503 ATH_TXBUF, DDI_DMA_STREAMING);
504 if (err != DDI_SUCCESS) {
505 ath_desc_free(asc);
506 return (err);
510 return (DDI_SUCCESS);
514 * declare ath_print* as possibly unused for non-DEBUG builds
516 static void
517 ath_printrxbuf(struct ath_buf *bf, int32_t done) __unused;
519 static void
520 ath_printtxbuf(struct ath_buf *bf, int done) __unused;
523 static void
524 ath_printrxbuf(struct ath_buf *bf, int32_t done)
526 struct ath_desc *ds = bf->bf_desc;
527 const struct ath_rx_status *rs = &bf->bf_status.ds_rxstat;
529 ATH_DEBUG((ATH_DBG_RECV, "ath: R (%p %p) %08x %08x %08x "
530 "%08x %08x %08x %c\n",
531 ds, bf->bf_daddr,
532 ds->ds_link, ds->ds_data,
533 ds->ds_ctl0, ds->ds_ctl1,
534 ds->ds_hw[0], ds->ds_hw[1],
535 !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'));
538 static void
539 ath_rx_handler(ath_t *asc)
541 ieee80211com_t *ic = (ieee80211com_t *)asc;
542 struct ath_buf *bf;
543 struct ath_hal *ah = asc->asc_ah;
544 struct ath_desc *ds;
545 struct ath_rx_status *rs;
546 mblk_t *rx_mp;
547 struct ieee80211_frame *wh;
548 int32_t len, loop = 1;
549 uint8_t phyerr;
550 HAL_STATUS status;
551 HAL_NODE_STATS hal_node_stats;
552 struct ieee80211_node *in;
554 do {
555 mutex_enter(&asc->asc_rxbuflock);
556 bf = list_head(&asc->asc_rxbuf_list);
557 if (bf == NULL) {
558 ATH_DEBUG((ATH_DBG_RECV, "ath: ath_rx_handler(): "
559 "no buffer\n"));
560 mutex_exit(&asc->asc_rxbuflock);
561 break;
563 ASSERT(bf->bf_dma.cookie.dmac_address != (uintptr_t)NULL);
564 ds = bf->bf_desc;
565 if (ds->ds_link == bf->bf_daddr) {
567 * Never process the self-linked entry at the end,
568 * this may be met at heavy load.
570 mutex_exit(&asc->asc_rxbuflock);
571 break;
574 rs = &bf->bf_status.ds_rxstat;
575 status = ATH_HAL_RXPROCDESC(ah, ds,
576 bf->bf_daddr,
577 ATH_PA2DESC(asc, ds->ds_link), rs);
578 if (status == HAL_EINPROGRESS) {
579 mutex_exit(&asc->asc_rxbuflock);
580 break;
582 list_remove(&asc->asc_rxbuf_list, bf);
583 mutex_exit(&asc->asc_rxbuflock);
585 if (rs->rs_status != 0) {
586 if (rs->rs_status & HAL_RXERR_CRC)
587 asc->asc_stats.ast_rx_crcerr++;
588 if (rs->rs_status & HAL_RXERR_FIFO)
589 asc->asc_stats.ast_rx_fifoerr++;
590 if (rs->rs_status & HAL_RXERR_DECRYPT)
591 asc->asc_stats.ast_rx_badcrypt++;
592 if (rs->rs_status & HAL_RXERR_PHY) {
593 asc->asc_stats.ast_rx_phyerr++;
594 phyerr = rs->rs_phyerr & 0x1f;
595 asc->asc_stats.ast_rx_phy[phyerr]++;
597 goto rx_next;
599 len = rs->rs_datalen;
601 /* less than sizeof(struct ieee80211_frame) */
602 if (len < 20) {
603 asc->asc_stats.ast_rx_tooshort++;
604 goto rx_next;
607 if ((rx_mp = allocb(asc->asc_dmabuf_size, BPRI_MED)) == NULL) {
608 ath_problem("ath: ath_rx_handler(): "
609 "allocing mblk buffer failed.\n");
610 return;
613 ATH_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORCPU);
614 bcopy(bf->bf_dma.mem_va, rx_mp->b_rptr, len);
616 rx_mp->b_wptr += len;
617 wh = (struct ieee80211_frame *)rx_mp->b_rptr;
618 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
619 IEEE80211_FC0_TYPE_CTL) {
621 * Ignore control frame received in promisc mode.
623 freemsg(rx_mp);
624 goto rx_next;
626 /* Remove the CRC at the end of IEEE80211 frame */
627 rx_mp->b_wptr -= IEEE80211_CRC_LEN;
628 #ifdef DEBUG
629 ath_printrxbuf(bf, status == HAL_OK);
630 #endif /* DEBUG */
632 * Locate the node for sender, track state, and then
633 * pass the (referenced) node up to the 802.11 layer
634 * for its use.
636 in = ieee80211_find_rxnode(ic, wh);
639 * Send frame up for processing.
641 (void) ieee80211_input(ic, rx_mp, in,
642 rs->rs_rssi, rs->rs_tstamp);
644 ieee80211_free_node(in);
646 rx_next:
647 mutex_enter(&asc->asc_rxbuflock);
648 list_insert_tail(&asc->asc_rxbuf_list, bf);
649 mutex_exit(&asc->asc_rxbuflock);
650 ath_setup_desc(asc, bf);
651 } while (loop);
653 /* rx signal state monitoring */
654 ATH_HAL_RXMONITOR(ah, &hal_node_stats, &asc->asc_curchan);
657 static void
658 ath_printtxbuf(struct ath_buf *bf, int done)
660 struct ath_desc *ds = bf->bf_desc;
661 const struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
663 ATH_DEBUG((ATH_DBG_SEND, "ath: T(%p %p) %08x %08x %08x %08x %08x"
664 " %08x %08x %08x %c\n",
665 ds, bf->bf_daddr,
666 ds->ds_link, ds->ds_data,
667 ds->ds_ctl0, ds->ds_ctl1,
668 ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
669 !done ? ' ' : (ts->ts_status == 0) ? '*' : '!'));
673 * The input parameter mp has following assumption:
674 * For data packets, GLDv3 mac_wifi plugin allocates and fills the
675 * ieee80211 header. For management packets, net80211 allocates and
676 * fills the ieee80211 header. In both cases, enough spaces in the
677 * header are left for encryption option.
679 static int32_t
680 ath_tx_start(ath_t *asc, struct ieee80211_node *in, struct ath_buf *bf,
681 mblk_t *mp)
683 ieee80211com_t *ic = (ieee80211com_t *)asc;
684 struct ieee80211_frame *wh;
685 struct ath_hal *ah = asc->asc_ah;
686 uint32_t subtype, flags, ctsduration;
687 int32_t keyix, iswep, hdrlen, pktlen, mblen, mbslen, try0;
688 uint8_t rix, cix, txrate, ctsrate;
689 struct ath_desc *ds;
690 struct ath_txq *txq;
691 HAL_PKT_TYPE atype;
692 const HAL_RATE_TABLE *rt;
693 HAL_BOOL shortPreamble;
694 struct ath_node *an;
695 caddr_t dest;
698 * CRC are added by H/W, not encaped by driver,
699 * but we must count it in pkt length.
701 pktlen = IEEE80211_CRC_LEN;
703 wh = (struct ieee80211_frame *)mp->b_rptr;
704 iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
705 keyix = HAL_TXKEYIX_INVALID;
706 hdrlen = sizeof (struct ieee80211_frame);
707 if (iswep != 0) {
708 const struct ieee80211_cipher *cip;
709 struct ieee80211_key *k;
712 * Construct the 802.11 header+trailer for an encrypted
713 * frame. The only reason this can fail is because of an
714 * unknown or unsupported cipher/key type.
716 k = ieee80211_crypto_encap(ic, mp);
717 if (k == NULL) {
718 ATH_DEBUG((ATH_DBG_AUX, "crypto_encap failed\n"));
720 * This can happen when the key is yanked after the
721 * frame was queued. Just discard the frame; the
722 * 802.11 layer counts failures and provides
723 * debugging/diagnostics.
725 return (EIO);
727 cip = k->wk_cipher;
729 * Adjust the packet + header lengths for the crypto
730 * additions and calculate the h/w key index. When
731 * a s/w mic is done the frame will have had any mic
732 * added to it prior to entry so m0->m_pkthdr.len above will
733 * account for it. Otherwise we need to add it to the
734 * packet length.
736 hdrlen += cip->ic_header;
737 pktlen += cip->ic_trailer;
738 if ((k->wk_flags & IEEE80211_KEY_SWMIC) == 0)
739 pktlen += cip->ic_miclen;
740 keyix = k->wk_keyix;
742 /* packet header may have moved, reset our local pointer */
743 wh = (struct ieee80211_frame *)mp->b_rptr;
746 dest = bf->bf_dma.mem_va;
747 for (; mp != NULL; mp = mp->b_cont) {
748 mblen = MBLKL(mp);
749 bcopy(mp->b_rptr, dest, mblen);
750 dest += mblen;
752 mbslen = (uintptr_t)dest - (uintptr_t)bf->bf_dma.mem_va;
753 pktlen += mbslen;
755 bf->bf_in = in;
757 /* setup descriptors */
758 ds = bf->bf_desc;
759 rt = asc->asc_currates;
760 ASSERT(rt != NULL);
763 * The 802.11 layer marks whether or not we should
764 * use short preamble based on the current mode and
765 * negotiated parameters.
767 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
768 (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
769 shortPreamble = AH_TRUE;
770 asc->asc_stats.ast_tx_shortpre++;
771 } else {
772 shortPreamble = AH_FALSE;
775 an = ATH_NODE(in);
778 * Calculate Atheros packet type from IEEE80211 packet header
779 * and setup for rate calculations.
781 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
782 case IEEE80211_FC0_TYPE_MGT:
783 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
784 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON)
785 atype = HAL_PKT_TYPE_BEACON;
786 else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
787 atype = HAL_PKT_TYPE_PROBE_RESP;
788 else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM)
789 atype = HAL_PKT_TYPE_ATIM;
790 else
791 atype = HAL_PKT_TYPE_NORMAL;
792 rix = 0; /* lowest rate */
793 try0 = ATH_TXMAXTRY;
794 if (shortPreamble)
795 txrate = an->an_tx_mgtratesp;
796 else
797 txrate = an->an_tx_mgtrate;
798 /* force all ctl frames to highest queue */
799 txq = asc->asc_ac2q[WME_AC_VO];
800 break;
801 case IEEE80211_FC0_TYPE_CTL:
802 atype = HAL_PKT_TYPE_PSPOLL;
803 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
804 rix = 0; /* lowest rate */
805 try0 = ATH_TXMAXTRY;
806 if (shortPreamble)
807 txrate = an->an_tx_mgtratesp;
808 else
809 txrate = an->an_tx_mgtrate;
810 /* force all ctl frames to highest queue */
811 txq = asc->asc_ac2q[WME_AC_VO];
812 break;
813 case IEEE80211_FC0_TYPE_DATA:
814 atype = HAL_PKT_TYPE_NORMAL;
815 rix = an->an_tx_rix0;
816 try0 = an->an_tx_try0;
817 if (shortPreamble)
818 txrate = an->an_tx_rate0sp;
819 else
820 txrate = an->an_tx_rate0;
821 /* Always use background queue */
822 txq = asc->asc_ac2q[WME_AC_BK];
823 break;
824 default:
825 /* Unknown 802.11 frame */
826 asc->asc_stats.ast_tx_invalid++;
827 return (1);
830 * Calculate miscellaneous flags.
832 flags = HAL_TXDESC_CLRDMASK;
833 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
834 flags |= HAL_TXDESC_NOACK; /* no ack on broad/multicast */
835 asc->asc_stats.ast_tx_noack++;
836 } else if (pktlen > ic->ic_rtsthreshold) {
837 flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */
838 asc->asc_stats.ast_tx_rts++;
842 * Calculate duration. This logically belongs in the 802.11
843 * layer but it lacks sufficient information to calculate it.
845 if ((flags & HAL_TXDESC_NOACK) == 0 &&
846 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
847 IEEE80211_FC0_TYPE_CTL) {
848 uint16_t dur;
849 dur = ath_hal_computetxtime(ah, rt, IEEE80211_ACK_SIZE,
850 rix, shortPreamble);
851 /* LINTED E_BAD_PTR_CAST_ALIGN */
852 *(uint16_t *)wh->i_dur = LE_16(dur);
856 * Calculate RTS/CTS rate and duration if needed.
858 ctsduration = 0;
859 if (flags & (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)) {
861 * CTS transmit rate is derived from the transmit rate
862 * by looking in the h/w rate table. We must also factor
863 * in whether or not a short preamble is to be used.
865 cix = rt->info[rix].controlRate;
866 ctsrate = rt->info[cix].rateCode;
867 if (shortPreamble)
868 ctsrate |= rt->info[cix].shortPreamble;
870 * Compute the transmit duration based on the size
871 * of an ACK frame. We call into the HAL to do the
872 * computation since it depends on the characteristics
873 * of the actual PHY being used.
875 if (flags & HAL_TXDESC_RTSENA) { /* SIFS + CTS */
876 ctsduration += ath_hal_computetxtime(ah,
877 rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
879 /* SIFS + data */
880 ctsduration += ath_hal_computetxtime(ah,
881 rt, pktlen, rix, shortPreamble);
882 if ((flags & HAL_TXDESC_NOACK) == 0) { /* SIFS + ACK */
883 ctsduration += ath_hal_computetxtime(ah,
884 rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
886 } else
887 ctsrate = 0;
889 if (++txq->axq_intrcnt >= ATH_TXINTR_PERIOD) {
890 flags |= HAL_TXDESC_INTREQ;
891 txq->axq_intrcnt = 0;
895 * Formulate first tx descriptor with tx controls.
897 ATH_HAL_SETUPTXDESC(ah, ds,
898 pktlen, /* packet length */
899 hdrlen, /* header length */
900 atype, /* Atheros packet type */
901 MIN(in->in_txpower, 60), /* txpower */
902 txrate, try0, /* series 0 rate/tries */
903 keyix, /* key cache index */
904 an->an_tx_antenna, /* antenna mode */
905 flags, /* flags */
906 ctsrate, /* rts/cts rate */
907 ctsduration); /* rts/cts duration */
908 bf->bf_flags = flags;
910 /* LINTED E_BAD_PTR_CAST_ALIGN */
911 ATH_DEBUG((ATH_DBG_SEND, "ath: ath_xmit(): to %s totlen=%d "
912 "an->an_tx_rate1sp=%d tx_rate2sp=%d tx_rate3sp=%d "
913 "qnum=%d rix=%d sht=%d dur = %d\n",
914 ieee80211_macaddr_sprintf(wh->i_addr1), mbslen, an->an_tx_rate1sp,
915 an->an_tx_rate2sp, an->an_tx_rate3sp,
916 txq->axq_qnum, rix, shortPreamble, *(uint16_t *)wh->i_dur));
919 * Setup the multi-rate retry state only when we're
920 * going to use it. This assumes ath_hal_setuptxdesc
921 * initializes the descriptors (so we don't have to)
922 * when the hardware supports multi-rate retry and
923 * we don't use it.
925 if (try0 != ATH_TXMAXTRY)
926 ATH_HAL_SETUPXTXDESC(ah, ds,
927 an->an_tx_rate1sp, 2, /* series 1 */
928 an->an_tx_rate2sp, 2, /* series 2 */
929 an->an_tx_rate3sp, 2); /* series 3 */
931 ds->ds_link = 0;
932 ds->ds_data = bf->bf_dma.cookie.dmac_address;
933 ATH_HAL_FILLTXDESC(ah, ds,
934 mbslen, /* segment length */
935 AH_TRUE, /* first segment */
936 AH_TRUE, /* last segment */
937 ds); /* first descriptor */
939 ATH_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV);
941 mutex_enter(&txq->axq_lock);
942 list_insert_tail(&txq->axq_list, bf);
943 if (txq->axq_link == NULL) {
944 ATH_HAL_PUTTXBUF(ah, txq->axq_qnum, bf->bf_daddr);
945 } else {
946 *txq->axq_link = bf->bf_daddr;
948 txq->axq_link = &ds->ds_link;
949 mutex_exit(&txq->axq_lock);
951 ATH_HAL_TXSTART(ah, txq->axq_qnum);
953 ic->ic_stats.is_tx_frags++;
954 ic->ic_stats.is_tx_bytes += pktlen;
956 return (0);
960 * Transmit a management frame. On failure we reclaim the skbuff.
961 * Note that management frames come directly from the 802.11 layer
962 * and do not honor the send queue flow control. Need to investigate
963 * using priority queueing so management frames can bypass data.
965 static int
966 ath_xmit(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
968 ath_t *asc = (ath_t *)ic;
969 struct ath_hal *ah = asc->asc_ah;
970 struct ieee80211_node *in = NULL;
971 struct ath_buf *bf = NULL;
972 struct ieee80211_frame *wh;
973 int error = 0;
975 ASSERT(mp->b_next == NULL);
977 if (!ATH_IS_RUNNING(asc)) {
978 if ((type & IEEE80211_FC0_TYPE_MASK) !=
979 IEEE80211_FC0_TYPE_DATA) {
980 freemsg(mp);
982 return (ENXIO);
985 /* Grab a TX buffer */
986 mutex_enter(&asc->asc_txbuflock);
987 bf = list_head(&asc->asc_txbuf_list);
988 if (bf != NULL)
989 list_remove(&asc->asc_txbuf_list, bf);
990 if (list_empty(&asc->asc_txbuf_list)) {
991 ATH_DEBUG((ATH_DBG_SEND, "ath: ath_mgmt_send(): "
992 "stop queue\n"));
993 asc->asc_stats.ast_tx_qstop++;
995 mutex_exit(&asc->asc_txbuflock);
996 if (bf == NULL) {
997 ATH_DEBUG((ATH_DBG_SEND, "ath: ath_mgmt_send(): discard, "
998 "no xmit buf\n"));
999 ic->ic_stats.is_tx_nobuf++;
1000 if ((type & IEEE80211_FC0_TYPE_MASK) ==
1001 IEEE80211_FC0_TYPE_DATA) {
1002 asc->asc_stats.ast_tx_nobuf++;
1003 mutex_enter(&asc->asc_resched_lock);
1004 asc->asc_resched_needed = B_TRUE;
1005 mutex_exit(&asc->asc_resched_lock);
1006 } else {
1007 asc->asc_stats.ast_tx_nobufmgt++;
1008 freemsg(mp);
1010 return (ENOMEM);
1013 wh = (struct ieee80211_frame *)mp->b_rptr;
1015 /* Locate node */
1016 in = ieee80211_find_txnode(ic, wh->i_addr1);
1017 if (in == NULL) {
1018 error = EIO;
1019 goto bad;
1022 in->in_inact = 0;
1023 switch (type & IEEE80211_FC0_TYPE_MASK) {
1024 case IEEE80211_FC0_TYPE_DATA:
1025 (void) ieee80211_encap(ic, mp, in);
1026 break;
1027 default:
1028 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1029 IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
1030 /* fill time stamp */
1031 uint64_t tsf;
1032 uint32_t *tstamp;
1034 tsf = ATH_HAL_GETTSF64(ah);
1035 /* adjust 100us delay to xmit */
1036 tsf += 100;
1037 /* LINTED E_BAD_PTR_CAST_ALIGN */
1038 tstamp = (uint32_t *)&wh[1];
1039 tstamp[0] = LE_32(tsf & 0xffffffff);
1040 tstamp[1] = LE_32(tsf >> 32);
1042 asc->asc_stats.ast_tx_mgmt++;
1043 break;
1046 error = ath_tx_start(asc, in, bf, mp);
1047 if (error != 0) {
1048 bad:
1049 ic->ic_stats.is_tx_failed++;
1050 if (bf != NULL) {
1051 mutex_enter(&asc->asc_txbuflock);
1052 list_insert_tail(&asc->asc_txbuf_list, bf);
1053 mutex_exit(&asc->asc_txbuflock);
1056 if (in != NULL)
1057 ieee80211_free_node(in);
1058 if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
1059 error == 0) {
1060 freemsg(mp);
1063 return (error);
1066 static mblk_t *
1067 ath_m_tx(void *arg, mblk_t *mp)
1069 ath_t *asc = arg;
1070 ieee80211com_t *ic = (ieee80211com_t *)asc;
1071 mblk_t *next;
1072 int error = 0;
1075 * No data frames go out unless we're associated; this
1076 * should not happen as the 802.11 layer does not enable
1077 * the xmit queue until we enter the RUN state.
1079 if (ic->ic_state != IEEE80211_S_RUN) {
1080 ATH_DEBUG((ATH_DBG_SEND, "ath: ath_m_tx(): "
1081 "discard, state %u\n", ic->ic_state));
1082 asc->asc_stats.ast_tx_discard++;
1083 freemsgchain(mp);
1084 return (NULL);
1087 while (mp != NULL) {
1088 next = mp->b_next;
1089 mp->b_next = NULL;
1090 error = ath_xmit(ic, mp, IEEE80211_FC0_TYPE_DATA);
1091 if (error != 0) {
1092 mp->b_next = next;
1093 if (error == ENOMEM) {
1094 break;
1095 } else {
1096 freemsgchain(mp); /* CR6501759 issues */
1097 return (NULL);
1100 mp = next;
1103 return (mp);
1106 static int
1107 ath_tx_processq(ath_t *asc, struct ath_txq *txq)
1109 ieee80211com_t *ic = (ieee80211com_t *)asc;
1110 struct ath_hal *ah = asc->asc_ah;
1111 struct ath_buf *bf;
1112 struct ath_desc *ds;
1113 struct ieee80211_node *in;
1114 int32_t sr, lr, nacked = 0;
1115 struct ath_tx_status *ts;
1116 HAL_STATUS status;
1117 struct ath_node *an;
1119 for (;;) {
1120 mutex_enter(&txq->axq_lock);
1121 bf = list_head(&txq->axq_list);
1122 if (bf == NULL) {
1123 txq->axq_link = NULL;
1124 mutex_exit(&txq->axq_lock);
1125 break;
1127 ds = bf->bf_desc; /* last decriptor */
1128 ts = &bf->bf_status.ds_txstat;
1129 status = ATH_HAL_TXPROCDESC(ah, ds, ts);
1130 #ifdef DEBUG
1131 ath_printtxbuf(bf, status == HAL_OK);
1132 #endif
1133 if (status == HAL_EINPROGRESS) {
1134 mutex_exit(&txq->axq_lock);
1135 break;
1137 list_remove(&txq->axq_list, bf);
1138 mutex_exit(&txq->axq_lock);
1139 in = bf->bf_in;
1140 if (in != NULL) {
1141 an = ATH_NODE(in);
1142 /* Successful transmition */
1143 if (ts->ts_status == 0) {
1144 an->an_tx_ok++;
1145 an->an_tx_antenna = ts->ts_antenna;
1146 if (ts->ts_rate & HAL_TXSTAT_ALTRATE)
1147 asc->asc_stats.ast_tx_altrate++;
1148 asc->asc_stats.ast_tx_rssidelta =
1149 ts->ts_rssi - asc->asc_stats.ast_tx_rssi;
1150 asc->asc_stats.ast_tx_rssi = ts->ts_rssi;
1151 } else {
1152 an->an_tx_err++;
1153 if (ts->ts_status & HAL_TXERR_XRETRY)
1154 asc->asc_stats.ast_tx_xretries++;
1155 if (ts->ts_status & HAL_TXERR_FIFO)
1156 asc->asc_stats.ast_tx_fifoerr++;
1157 if (ts->ts_status & HAL_TXERR_FILT)
1158 asc->asc_stats.ast_tx_filtered++;
1159 an->an_tx_antenna = 0; /* invalidate */
1161 sr = ts->ts_shortretry;
1162 lr = ts->ts_longretry;
1163 asc->asc_stats.ast_tx_shortretry += sr;
1164 asc->asc_stats.ast_tx_longretry += lr;
1166 * Hand the descriptor to the rate control algorithm.
1168 if ((ts->ts_status & HAL_TXERR_FILT) == 0 &&
1169 (bf->bf_flags & HAL_TXDESC_NOACK) == 0) {
1171 * If frame was ack'd update the last rx time
1172 * used to workaround phantom bmiss interrupts.
1174 if (ts->ts_status == 0) {
1175 nacked++;
1176 an->an_tx_ok++;
1177 } else {
1178 an->an_tx_err++;
1180 an->an_tx_retr += sr + lr;
1183 bf->bf_in = NULL;
1184 mutex_enter(&asc->asc_txbuflock);
1185 list_insert_tail(&asc->asc_txbuf_list, bf);
1186 mutex_exit(&asc->asc_txbuflock);
1188 * Reschedule stalled outbound packets
1190 mutex_enter(&asc->asc_resched_lock);
1191 if (asc->asc_resched_needed) {
1192 asc->asc_resched_needed = B_FALSE;
1193 mac_tx_update(ic->ic_mach);
1195 mutex_exit(&asc->asc_resched_lock);
1197 return (nacked);
1201 static void
1202 ath_tx_handler(ath_t *asc)
1204 int i;
1207 * Process each active queue.
1209 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
1210 if (ATH_TXQ_SETUP(asc, i)) {
1211 (void) ath_tx_processq(asc, &asc->asc_txq[i]);
1216 static struct ieee80211_node *
1217 ath_node_alloc(ieee80211com_t *ic)
1219 struct ath_node *an;
1220 ath_t *asc = (ath_t *)ic;
1222 an = kmem_zalloc(sizeof (struct ath_node), KM_SLEEP);
1223 ath_rate_update(asc, &an->an_node, 0);
1224 return (&an->an_node);
1227 static void
1228 ath_node_free(struct ieee80211_node *in)
1230 ieee80211com_t *ic = in->in_ic;
1231 ath_t *asc = (ath_t *)ic;
1232 struct ath_buf *bf;
1233 struct ath_txq *txq;
1234 int32_t i;
1236 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
1237 if (ATH_TXQ_SETUP(asc, i)) {
1238 txq = &asc->asc_txq[i];
1239 mutex_enter(&txq->axq_lock);
1240 bf = list_head(&txq->axq_list);
1241 while (bf != NULL) {
1242 if (bf->bf_in == in) {
1243 bf->bf_in = NULL;
1245 bf = list_next(&txq->axq_list, bf);
1247 mutex_exit(&txq->axq_lock);
1250 ic->ic_node_cleanup(in);
1251 if (in->in_wpa_ie != NULL)
1252 ieee80211_free(in->in_wpa_ie);
1253 kmem_free(in, sizeof (struct ath_node));
1256 static void
1257 ath_next_scan(void *arg)
1259 ieee80211com_t *ic = arg;
1260 ath_t *asc = (ath_t *)ic;
1262 asc->asc_scan_timer = 0;
1263 if (ic->ic_state == IEEE80211_S_SCAN) {
1264 asc->asc_scan_timer = timeout(ath_next_scan, (void *)asc,
1265 drv_usectohz(ath_dwelltime * 1000));
1266 ieee80211_next_scan(ic);
1270 static void
1271 ath_stop_scantimer(ath_t *asc)
1273 timeout_id_t tmp_id = 0;
1275 while ((asc->asc_scan_timer != 0) && (tmp_id != asc->asc_scan_timer)) {
1276 tmp_id = asc->asc_scan_timer;
1277 (void) untimeout(tmp_id);
1279 asc->asc_scan_timer = 0;
1282 static int32_t
1283 ath_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
1285 ath_t *asc = (ath_t *)ic;
1286 struct ath_hal *ah = asc->asc_ah;
1287 struct ieee80211_node *in;
1288 int32_t i, error;
1289 uint8_t *bssid;
1290 uint32_t rfilt;
1291 enum ieee80211_state ostate;
1293 static const HAL_LED_STATE leds[] = {
1294 HAL_LED_INIT, /* IEEE80211_S_INIT */
1295 HAL_LED_SCAN, /* IEEE80211_S_SCAN */
1296 HAL_LED_AUTH, /* IEEE80211_S_AUTH */
1297 HAL_LED_ASSOC, /* IEEE80211_S_ASSOC */
1298 HAL_LED_RUN, /* IEEE80211_S_RUN */
1300 if (!ATH_IS_RUNNING(asc))
1301 return (0);
1303 ostate = ic->ic_state;
1304 if (nstate != IEEE80211_S_SCAN)
1305 ath_stop_scantimer(asc);
1307 ATH_LOCK(asc);
1308 ATH_HAL_SETLEDSTATE(ah, leds[nstate]); /* set LED */
1310 if (nstate == IEEE80211_S_INIT) {
1311 asc->asc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
1313 * Disable interrupts.
1315 ATH_HAL_INTRSET(ah, asc->asc_imask &~ HAL_INT_GLOBAL);
1316 ATH_UNLOCK(asc);
1317 goto done;
1319 in = ic->ic_bss;
1320 error = ath_chan_set(asc, ic->ic_curchan);
1321 if (error != 0) {
1322 if (nstate != IEEE80211_S_SCAN) {
1323 ATH_UNLOCK(asc);
1324 ieee80211_reset_chan(ic);
1325 goto bad;
1329 rfilt = ath_calcrxfilter(asc);
1331 if (nstate == IEEE80211_S_SCAN)
1332 bssid = ic->ic_macaddr;
1333 else
1334 bssid = in->in_bssid;
1335 ATH_HAL_SETRXFILTER(ah, rfilt);
1337 if (nstate == IEEE80211_S_RUN && ic->ic_opmode != IEEE80211_M_IBSS)
1338 ATH_HAL_SETASSOCID(ah, bssid, in->in_associd);
1339 else
1340 ATH_HAL_SETASSOCID(ah, bssid, 0);
1341 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
1342 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1343 if (ATH_HAL_KEYISVALID(ah, i))
1344 ATH_HAL_KEYSETMAC(ah, i, bssid);
1348 if ((nstate == IEEE80211_S_RUN) &&
1349 (ostate != IEEE80211_S_RUN)) {
1350 /* Configure the beacon and sleep timers. */
1351 ath_beacon_config(asc);
1352 } else {
1353 asc->asc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
1354 ATH_HAL_INTRSET(ah, asc->asc_imask);
1357 * Reset the rate control state.
1359 ath_rate_ctl_reset(asc, nstate);
1361 ATH_UNLOCK(asc);
1362 done:
1364 * Invoke the parent method to complete the work.
1366 error = asc->asc_newstate(ic, nstate, arg);
1368 * Finally, start any timers.
1370 if (nstate == IEEE80211_S_RUN) {
1371 ieee80211_start_watchdog(ic, 1);
1372 } else if ((nstate == IEEE80211_S_SCAN) && (ostate != nstate)) {
1373 /* start ap/neighbor scan timer */
1374 ASSERT(asc->asc_scan_timer == 0);
1375 asc->asc_scan_timer = timeout(ath_next_scan, (void *)asc,
1376 drv_usectohz(ath_dwelltime * 1000));
1378 bad:
1379 return (error);
1383 * Periodically recalibrate the PHY to account
1384 * for temperature/environment changes.
1386 static void
1387 ath_calibrate(ath_t *asc)
1389 struct ath_hal *ah = asc->asc_ah;
1390 HAL_BOOL iqcaldone;
1392 asc->asc_stats.ast_per_cal++;
1394 if (ATH_HAL_GETRFGAIN(ah) == HAL_RFGAIN_NEED_CHANGE) {
1396 * Rfgain is out of bounds, reset the chip
1397 * to load new gain values.
1399 ATH_DEBUG((ATH_DBG_HAL, "ath: ath_calibrate(): "
1400 "Need change RFgain\n"));
1401 asc->asc_stats.ast_per_rfgain++;
1402 (void) ath_reset(&asc->asc_isc);
1404 if (!ATH_HAL_CALIBRATE(ah, &asc->asc_curchan, &iqcaldone)) {
1405 ATH_DEBUG((ATH_DBG_HAL, "ath: ath_calibrate(): "
1406 "calibration of channel %u failed\n",
1407 asc->asc_curchan.channel));
1408 asc->asc_stats.ast_per_calfail++;
1412 static void
1413 ath_watchdog(void *arg)
1415 ath_t *asc = arg;
1416 ieee80211com_t *ic = &asc->asc_isc;
1417 int ntimer = 0;
1419 ATH_LOCK(asc);
1420 ic->ic_watchdog_timer = 0;
1421 if (!ATH_IS_RUNNING(asc)) {
1422 ATH_UNLOCK(asc);
1423 return;
1426 if (ic->ic_state == IEEE80211_S_RUN) {
1427 /* periodic recalibration */
1428 ath_calibrate(asc);
1431 * Start the background rate control thread if we
1432 * are not configured to use a fixed xmit rate.
1434 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
1435 asc->asc_stats.ast_rate_calls ++;
1436 if (ic->ic_opmode == IEEE80211_M_STA)
1437 ath_rate_ctl(ic, ic->ic_bss);
1438 else
1439 ieee80211_iterate_nodes(&ic->ic_sta,
1440 ath_rate_ctl, asc);
1443 ntimer = 1;
1445 ATH_UNLOCK(asc);
1447 ieee80211_watchdog(ic);
1448 if (ntimer != 0)
1449 ieee80211_start_watchdog(ic, ntimer);
1452 static void
1453 ath_tx_proc(void *arg)
1455 ath_t *asc = arg;
1456 ath_tx_handler(asc);
1460 static uint_t
1461 ath_intr(caddr_t arg)
1463 /* LINTED E_BAD_PTR_CAST_ALIGN */
1464 ath_t *asc = (ath_t *)arg;
1465 struct ath_hal *ah = asc->asc_ah;
1466 HAL_INT status;
1467 ieee80211com_t *ic = (ieee80211com_t *)asc;
1469 ATH_LOCK(asc);
1471 if (!ATH_IS_RUNNING(asc)) {
1473 * The hardware is not ready/present, don't touch anything.
1474 * Note this can happen early on if the IRQ is shared.
1476 ATH_UNLOCK(asc);
1477 return (DDI_INTR_UNCLAIMED);
1480 if (!ATH_HAL_INTRPEND(ah)) { /* shared irq, not for us */
1481 ATH_UNLOCK(asc);
1482 return (DDI_INTR_UNCLAIMED);
1485 ATH_HAL_GETISR(ah, &status);
1486 status &= asc->asc_imask;
1487 if (status & HAL_INT_FATAL) {
1488 asc->asc_stats.ast_hardware++;
1489 goto reset;
1490 } else if (status & HAL_INT_RXORN) {
1491 asc->asc_stats.ast_rxorn++;
1492 goto reset;
1493 } else {
1494 if (status & HAL_INT_RXEOL) {
1495 asc->asc_stats.ast_rxeol++;
1496 asc->asc_rxlink = NULL;
1498 if (status & HAL_INT_TXURN) {
1499 asc->asc_stats.ast_txurn++;
1500 ATH_HAL_UPDATETXTRIGLEVEL(ah, AH_TRUE);
1503 if (status & HAL_INT_RX) {
1504 asc->asc_rx_pend = 1;
1505 ddi_trigger_softintr(asc->asc_softint_id);
1507 if (status & HAL_INT_TX) {
1508 if (ddi_taskq_dispatch(asc->asc_tq, ath_tx_proc,
1509 asc, DDI_NOSLEEP) != DDI_SUCCESS) {
1510 ath_problem("ath: ath_intr(): "
1511 "No memory available for tx taskq\n");
1514 ATH_UNLOCK(asc);
1516 if (status & HAL_INT_SWBA) {
1517 /* This will occur only in Host-AP or Ad-Hoc mode */
1518 return (DDI_INTR_CLAIMED);
1521 if (status & HAL_INT_BMISS) {
1522 if (ic->ic_state == IEEE80211_S_RUN) {
1523 (void) ieee80211_new_state(ic,
1524 IEEE80211_S_ASSOC, -1);
1530 return (DDI_INTR_CLAIMED);
1531 reset:
1532 (void) ath_reset(ic);
1533 ATH_UNLOCK(asc);
1534 return (DDI_INTR_CLAIMED);
1537 static uint_t
1538 ath_softint_handler(caddr_t data)
1540 /* LINTED E_BAD_PTR_CAST_ALIGN */
1541 ath_t *asc = (ath_t *)data;
1544 * Check if the soft interrupt is triggered by another
1545 * driver at the same level.
1547 ATH_LOCK(asc);
1548 if (asc->asc_rx_pend) { /* Soft interrupt for this driver */
1549 asc->asc_rx_pend = 0;
1550 ATH_UNLOCK(asc);
1551 ath_rx_handler(asc);
1552 return (DDI_INTR_CLAIMED);
1554 ATH_UNLOCK(asc);
1555 return (DDI_INTR_UNCLAIMED);
1559 * following are gld callback routine
1560 * ath_gld_send, ath_gld_ioctl, ath_gld_gstat
1561 * are listed in other corresponding sections.
1562 * reset the hardware w/o losing operational state. this is
1563 * basically a more efficient way of doing ath_gld_stop, ath_gld_start,
1564 * followed by state transitions to the current 802.11
1565 * operational state. used to recover from errors rx overrun
1566 * and to reset the hardware when rf gain settings must be reset.
1569 static void
1570 ath_stop_locked(ath_t *asc)
1572 ieee80211com_t *ic = (ieee80211com_t *)asc;
1573 struct ath_hal *ah = asc->asc_ah;
1575 ATH_LOCK_ASSERT(asc);
1576 if (!asc->asc_isrunning)
1577 return;
1580 * Shutdown the hardware and driver:
1581 * reset 802.11 state machine
1582 * turn off timers
1583 * disable interrupts
1584 * turn off the radio
1585 * clear transmit machinery
1586 * clear receive machinery
1587 * drain and release tx queues
1588 * reclaim beacon resources
1589 * power down hardware
1591 * Note that some of this work is not possible if the
1592 * hardware is gone (invalid).
1594 ATH_UNLOCK(asc);
1595 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1596 ieee80211_stop_watchdog(ic);
1597 ATH_LOCK(asc);
1598 ATH_HAL_INTRSET(ah, 0);
1599 ath_draintxq(asc);
1600 if (!asc->asc_invalid) {
1601 ath_stoprecv(asc);
1602 ATH_HAL_PHYDISABLE(ah);
1603 } else {
1604 asc->asc_rxlink = NULL;
1606 asc->asc_isrunning = 0;
1609 static void
1610 ath_m_stop(void *arg)
1612 ath_t *asc = arg;
1613 struct ath_hal *ah = asc->asc_ah;
1615 ATH_LOCK(asc);
1616 ath_stop_locked(asc);
1617 ATH_HAL_SETPOWER(ah, HAL_PM_AWAKE);
1618 asc->asc_invalid = 1;
1619 ATH_UNLOCK(asc);
1622 static int
1623 ath_start_locked(ath_t *asc)
1625 ieee80211com_t *ic = (ieee80211com_t *)asc;
1626 struct ath_hal *ah = asc->asc_ah;
1627 HAL_STATUS status;
1629 ATH_LOCK_ASSERT(asc);
1632 * The basic interface to setting the hardware in a good
1633 * state is ``reset''. On return the hardware is known to
1634 * be powered up and with interrupts disabled. This must
1635 * be followed by initialization of the appropriate bits
1636 * and then setup of the interrupt mask.
1638 asc->asc_curchan.channel = ic->ic_curchan->ich_freq;
1639 asc->asc_curchan.channelFlags = ath_chan2flags(ic, ic->ic_curchan);
1640 if (!ATH_HAL_RESET(ah, (HAL_OPMODE)ic->ic_opmode,
1641 &asc->asc_curchan, AH_FALSE, &status)) {
1642 ATH_DEBUG((ATH_DBG_HAL, "ath: ath_m_start(): "
1643 "reset hardware failed: '%s' (HAL status %u)\n",
1644 ath_get_hal_status_desc(status), status));
1645 return (ENOTACTIVE);
1648 (void) ath_startrecv(asc);
1651 * Enable interrupts.
1653 asc->asc_imask = HAL_INT_RX | HAL_INT_TX
1654 | HAL_INT_RXEOL | HAL_INT_RXORN
1655 | HAL_INT_FATAL | HAL_INT_GLOBAL;
1656 ATH_HAL_INTRSET(ah, asc->asc_imask);
1659 * The hardware should be ready to go now so it's safe
1660 * to kick the 802.11 state machine as it's likely to
1661 * immediately call back to us to send mgmt frames.
1663 ath_chan_change(asc, ic->ic_curchan);
1665 asc->asc_isrunning = 1;
1667 return (0);
1671 ath_m_start(void *arg)
1673 ath_t *asc = arg;
1674 int err;
1676 ATH_LOCK(asc);
1678 * Stop anything previously setup. This is safe
1679 * whether this is the first time through or not.
1681 ath_stop_locked(asc);
1683 if ((err = ath_start_locked(asc)) != 0) {
1684 ATH_UNLOCK(asc);
1685 return (err);
1688 asc->asc_invalid = 0;
1689 ATH_UNLOCK(asc);
1691 return (0);
1695 static int
1696 ath_m_unicst(void *arg, const uint8_t *macaddr)
1698 ath_t *asc = arg;
1699 struct ath_hal *ah = asc->asc_ah;
1701 ATH_DEBUG((ATH_DBG_GLD, "ath: ath_gld_saddr(): "
1702 "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1703 macaddr[0], macaddr[1], macaddr[2],
1704 macaddr[3], macaddr[4], macaddr[5]));
1706 ATH_LOCK(asc);
1707 IEEE80211_ADDR_COPY(asc->asc_isc.ic_macaddr, macaddr);
1708 ATH_HAL_SETMAC(ah, asc->asc_isc.ic_macaddr);
1710 (void) ath_reset(&asc->asc_isc);
1711 ATH_UNLOCK(asc);
1712 return (0);
1715 static int
1716 ath_m_promisc(void *arg, boolean_t on)
1718 ath_t *asc = arg;
1719 struct ath_hal *ah = asc->asc_ah;
1720 uint32_t rfilt;
1722 ATH_LOCK(asc);
1723 rfilt = ATH_HAL_GETRXFILTER(ah);
1724 if (on)
1725 rfilt |= HAL_RX_FILTER_PROM;
1726 else
1727 rfilt &= ~HAL_RX_FILTER_PROM;
1728 asc->asc_promisc = on;
1729 ATH_HAL_SETRXFILTER(ah, rfilt);
1730 ATH_UNLOCK(asc);
1732 return (0);
1735 static int
1736 ath_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
1738 ath_t *asc = arg;
1739 struct ath_hal *ah = asc->asc_ah;
1740 uint32_t val, index, bit;
1741 uint8_t pos;
1742 uint32_t *mfilt = asc->asc_mcast_hash;
1744 ATH_LOCK(asc);
1746 /* calculate XOR of eight 6bit values */
1747 val = ATH_LE_READ_4(mca + 0);
1748 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
1749 val = ATH_LE_READ_4(mca + 3);
1750 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
1751 pos &= 0x3f;
1752 index = pos / 32;
1753 bit = 1 << (pos % 32);
1755 if (add) { /* enable multicast */
1756 asc->asc_mcast_refs[pos]++;
1757 mfilt[index] |= bit;
1758 } else { /* disable multicast */
1759 if (--asc->asc_mcast_refs[pos] == 0)
1760 mfilt[index] &= ~bit;
1762 ATH_HAL_SETMCASTFILTER(ah, mfilt[0], mfilt[1]);
1764 ATH_UNLOCK(asc);
1765 return (0);
1768 * callback functions for /get/set properties
1770 static int
1771 ath_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
1772 uint_t wldp_length, const void *wldp_buf)
1774 ath_t *asc = arg;
1775 int err;
1777 err = ieee80211_setprop(&asc->asc_isc, pr_name, wldp_pr_num,
1778 wldp_length, wldp_buf);
1780 ATH_LOCK(asc);
1782 if (err == ENETRESET) {
1783 if (ATH_IS_RUNNING(asc)) {
1784 ATH_UNLOCK(asc);
1785 (void) ath_m_start(asc);
1786 (void) ieee80211_new_state(&asc->asc_isc,
1787 IEEE80211_S_SCAN, -1);
1788 ATH_LOCK(asc);
1790 err = 0;
1793 ATH_UNLOCK(asc);
1795 return (err);
1798 static int
1799 ath_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
1800 uint_t wldp_length, void *wldp_buf)
1802 ath_t *asc = arg;
1803 int err = 0;
1805 err = ieee80211_getprop(&asc->asc_isc, pr_name, wldp_pr_num,
1806 wldp_length, wldp_buf);
1808 return (err);
1811 static void
1812 ath_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
1813 mac_prop_info_handle_t mph)
1815 ath_t *asc = arg;
1817 ieee80211_propinfo(&asc->asc_isc, pr_name, wldp_pr_num, mph);
1820 static void
1821 ath_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
1823 ath_t *asc = arg;
1824 int32_t err;
1826 err = ieee80211_ioctl(&asc->asc_isc, wq, mp);
1827 ATH_LOCK(asc);
1828 if (err == ENETRESET) {
1829 if (ATH_IS_RUNNING(asc)) {
1830 ATH_UNLOCK(asc);
1831 (void) ath_m_start(asc);
1832 (void) ieee80211_new_state(&asc->asc_isc,
1833 IEEE80211_S_SCAN, -1);
1834 ATH_LOCK(asc);
1837 ATH_UNLOCK(asc);
1840 static int
1841 ath_m_stat(void *arg, uint_t stat, uint64_t *val)
1843 ath_t *asc = arg;
1844 ieee80211com_t *ic = (ieee80211com_t *)asc;
1845 struct ieee80211_node *in = ic->ic_bss;
1846 struct ieee80211_rateset *rs = &in->in_rates;
1848 ATH_LOCK(asc);
1849 switch (stat) {
1850 case MAC_STAT_IFSPEED:
1851 *val = (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2 *
1852 1000000ull;
1853 break;
1854 case MAC_STAT_NOXMTBUF:
1855 *val = asc->asc_stats.ast_tx_nobuf +
1856 asc->asc_stats.ast_tx_nobufmgt;
1857 break;
1858 case MAC_STAT_IERRORS:
1859 *val = asc->asc_stats.ast_rx_tooshort;
1860 break;
1861 case MAC_STAT_RBYTES:
1862 *val = ic->ic_stats.is_rx_bytes;
1863 break;
1864 case MAC_STAT_IPACKETS:
1865 *val = ic->ic_stats.is_rx_frags;
1866 break;
1867 case MAC_STAT_OBYTES:
1868 *val = ic->ic_stats.is_tx_bytes;
1869 break;
1870 case MAC_STAT_OPACKETS:
1871 *val = ic->ic_stats.is_tx_frags;
1872 break;
1873 case MAC_STAT_OERRORS:
1874 case WIFI_STAT_TX_FAILED:
1875 *val = asc->asc_stats.ast_tx_fifoerr +
1876 asc->asc_stats.ast_tx_xretries +
1877 asc->asc_stats.ast_tx_discard;
1878 break;
1879 case WIFI_STAT_TX_RETRANS:
1880 *val = asc->asc_stats.ast_tx_xretries;
1881 break;
1882 case WIFI_STAT_FCS_ERRORS:
1883 *val = asc->asc_stats.ast_rx_crcerr;
1884 break;
1885 case WIFI_STAT_WEP_ERRORS:
1886 *val = asc->asc_stats.ast_rx_badcrypt;
1887 break;
1888 case WIFI_STAT_TX_FRAGS:
1889 case WIFI_STAT_MCAST_TX:
1890 case WIFI_STAT_RTS_SUCCESS:
1891 case WIFI_STAT_RTS_FAILURE:
1892 case WIFI_STAT_ACK_FAILURE:
1893 case WIFI_STAT_RX_FRAGS:
1894 case WIFI_STAT_MCAST_RX:
1895 case WIFI_STAT_RX_DUPS:
1896 ATH_UNLOCK(asc);
1897 return (ieee80211_stat(ic, stat, val));
1898 default:
1899 ATH_UNLOCK(asc);
1900 return (ENOTSUP);
1902 ATH_UNLOCK(asc);
1904 return (0);
1907 static int
1908 ath_pci_setup(ath_t *asc)
1910 uint16_t command;
1913 * Enable memory mapping and bus mastering
1915 ASSERT(asc != NULL);
1916 command = pci_config_get16(asc->asc_cfg_handle, PCI_CONF_COMM);
1917 command |= PCI_COMM_MAE | PCI_COMM_ME;
1918 pci_config_put16(asc->asc_cfg_handle, PCI_CONF_COMM, command);
1919 command = pci_config_get16(asc->asc_cfg_handle, PCI_CONF_COMM);
1920 if ((command & PCI_COMM_MAE) == 0) {
1921 ath_problem("ath: ath_pci_setup(): "
1922 "failed to enable memory mapping\n");
1923 return (EIO);
1925 if ((command & PCI_COMM_ME) == 0) {
1926 ath_problem("ath: ath_pci_setup(): "
1927 "failed to enable bus mastering\n");
1928 return (EIO);
1930 ATH_DEBUG((ATH_DBG_INIT, "ath: ath_pci_setup(): "
1931 "set command reg to 0x%x \n", command));
1933 return (0);
1936 static int
1937 ath_resume(dev_info_t *devinfo)
1939 ath_t *asc;
1940 int ret = DDI_SUCCESS;
1942 asc = ddi_get_soft_state(ath_soft_state_p, ddi_get_instance(devinfo));
1943 if (asc == NULL) {
1944 ATH_DEBUG((ATH_DBG_SUSPEND, "ath: ath_resume(): "
1945 "failed to get soft state\n"));
1946 return (DDI_FAILURE);
1949 ATH_LOCK(asc);
1951 * Set up config space command register(s). Refuse
1952 * to resume on failure.
1954 if (ath_pci_setup(asc) != 0) {
1955 ATH_DEBUG((ATH_DBG_SUSPEND, "ath: ath_resume(): "
1956 "ath_pci_setup() failed\n"));
1957 ATH_UNLOCK(asc);
1958 return (DDI_FAILURE);
1961 if (!asc->asc_invalid)
1962 ret = ath_start_locked(asc);
1963 ATH_UNLOCK(asc);
1965 return (ret);
1968 static int
1969 ath_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
1971 ath_t *asc;
1972 ieee80211com_t *ic;
1973 struct ath_hal *ah;
1974 uint8_t csz;
1975 HAL_STATUS status;
1976 caddr_t regs;
1977 uint32_t i, val;
1978 uint16_t vendor_id, device_id;
1979 const char *athname;
1980 int32_t ath_countrycode = CTRY_DEFAULT; /* country code */
1981 int32_t err, ath_regdomain = 0; /* regulatory domain */
1982 char strbuf[32];
1983 int instance;
1984 wifi_data_t wd = { 0 };
1985 mac_register_t *macp;
1987 switch (cmd) {
1988 case DDI_ATTACH:
1989 break;
1991 case DDI_RESUME:
1992 return (ath_resume(devinfo));
1994 default:
1995 return (DDI_FAILURE);
1998 instance = ddi_get_instance(devinfo);
1999 if (ddi_soft_state_zalloc(ath_soft_state_p, instance) != DDI_SUCCESS) {
2000 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2001 "Unable to alloc softstate\n"));
2002 return (DDI_FAILURE);
2005 asc = ddi_get_soft_state(ath_soft_state_p, ddi_get_instance(devinfo));
2006 ic = (ieee80211com_t *)asc;
2007 asc->asc_dev = devinfo;
2009 mutex_init(&asc->asc_genlock, NULL, MUTEX_DRIVER, NULL);
2010 mutex_init(&asc->asc_txbuflock, NULL, MUTEX_DRIVER, NULL);
2011 mutex_init(&asc->asc_rxbuflock, NULL, MUTEX_DRIVER, NULL);
2012 mutex_init(&asc->asc_resched_lock, NULL, MUTEX_DRIVER, NULL);
2014 err = pci_config_setup(devinfo, &asc->asc_cfg_handle);
2015 if (err != DDI_SUCCESS) {
2016 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2017 "pci_config_setup() failed"));
2018 goto attach_fail0;
2021 if (ath_pci_setup(asc) != 0)
2022 goto attach_fail1;
2025 * Cache line size is used to size and align various
2026 * structures used to communicate with the hardware.
2028 csz = pci_config_get8(asc->asc_cfg_handle, PCI_CONF_CACHE_LINESZ);
2029 if (csz == 0) {
2031 * We must have this setup properly for rx buffer
2032 * DMA to work so force a reasonable value here if it
2033 * comes up zero.
2035 csz = ATH_DEF_CACHE_BYTES / sizeof (uint32_t);
2036 pci_config_put8(asc->asc_cfg_handle, PCI_CONF_CACHE_LINESZ,
2037 csz);
2039 asc->asc_cachelsz = csz << 2;
2040 vendor_id = pci_config_get16(asc->asc_cfg_handle, PCI_CONF_VENID);
2041 device_id = pci_config_get16(asc->asc_cfg_handle, PCI_CONF_DEVID);
2042 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): vendor 0x%x, "
2043 "device id 0x%x, cache size %d\n", vendor_id, device_id, csz));
2045 athname = ath_hal_probe(vendor_id, device_id);
2046 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): athname: %s\n",
2047 athname ? athname : "Atheros ???"));
2049 pci_config_put8(asc->asc_cfg_handle, PCI_CONF_LATENCY_TIMER, 0xa8);
2050 val = pci_config_get32(asc->asc_cfg_handle, 0x40);
2051 if ((val & 0x0000ff00) != 0)
2052 pci_config_put32(asc->asc_cfg_handle, 0x40, val & 0xffff00ff);
2054 err = ddi_regs_map_setup(devinfo, 1,
2055 &regs, 0, 0, &ath_reg_accattr, &asc->asc_io_handle);
2056 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2057 "regs map1 = %x err=%d\n", regs, err));
2058 if (err != DDI_SUCCESS) {
2059 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2060 "ddi_regs_map_setup() failed"));
2061 goto attach_fail1;
2064 ah = ath_hal_attach(device_id, asc, 0, regs, &status);
2065 if (ah == NULL) {
2066 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2067 "unable to attach hw: '%s' (HAL status %u)\n",
2068 ath_get_hal_status_desc(status), status));
2069 goto attach_fail2;
2071 ATH_DEBUG((ATH_DBG_ATTACH, "mac %d.%d phy %d.%d",
2072 ah->ah_macVersion, ah->ah_macRev,
2073 ah->ah_phyRev >> 4, ah->ah_phyRev & 0xf));
2074 ATH_HAL_INTRSET(ah, 0);
2075 asc->asc_ah = ah;
2077 if (ah->ah_abi != HAL_ABI_VERSION) {
2078 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2079 "HAL ABI mismatch detected (0x%x != 0x%x)\n",
2080 ah->ah_abi, HAL_ABI_VERSION));
2081 goto attach_fail3;
2084 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2085 "HAL ABI version 0x%x\n", ah->ah_abi));
2086 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2087 "HAL mac version %d.%d, phy version %d.%d\n",
2088 ah->ah_macVersion, ah->ah_macRev,
2089 ah->ah_phyRev >> 4, ah->ah_phyRev & 0xf));
2090 if (ah->ah_analog5GhzRev)
2091 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2092 "HAL 5ghz radio version %d.%d\n",
2093 ah->ah_analog5GhzRev >> 4,
2094 ah->ah_analog5GhzRev & 0xf));
2095 if (ah->ah_analog2GhzRev)
2096 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2097 "HAL 2ghz radio version %d.%d\n",
2098 ah->ah_analog2GhzRev >> 4,
2099 ah->ah_analog2GhzRev & 0xf));
2102 * Check if the MAC has multi-rate retry support.
2103 * We do this by trying to setup a fake extended
2104 * descriptor. MAC's that don't have support will
2105 * return false w/o doing anything. MAC's that do
2106 * support it will return true w/o doing anything.
2108 asc->asc_mrretry = ATH_HAL_SETUPXTXDESC(ah, NULL, 0, 0, 0, 0, 0, 0);
2109 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2110 "multi rate retry support=%x\n",
2111 asc->asc_mrretry));
2114 * Get the hardware key cache size.
2116 asc->asc_keymax = ATH_HAL_KEYCACHESIZE(ah);
2117 if (asc->asc_keymax > sizeof (asc->asc_keymap) * NBBY) {
2118 ATH_DEBUG((ATH_DBG_ATTACH, "ath_attach:"
2119 " Warning, using only %u entries in %u key cache\n",
2120 sizeof (asc->asc_keymap) * NBBY, asc->asc_keymax));
2121 asc->asc_keymax = sizeof (asc->asc_keymap) * NBBY;
2124 * Reset the key cache since some parts do not
2125 * reset the contents on initial power up.
2127 for (i = 0; i < asc->asc_keymax; i++)
2128 ATH_HAL_KEYRESET(ah, i);
2130 ATH_HAL_GETREGDOMAIN(ah, (uint32_t *)&ath_regdomain);
2131 ATH_HAL_GETCOUNTRYCODE(ah, &ath_countrycode);
2133 * Collect the channel list using the default country
2134 * code and including outdoor channels. The 802.11 layer
2135 * is resposible for filtering this list to a set of
2136 * channels that it considers ok to use.
2138 asc->asc_have11g = 0;
2140 /* enable outdoor use, enable extended channels */
2141 err = ath_getchannels(asc, ath_countrycode, AH_FALSE, AH_TRUE);
2142 if (err != 0)
2143 goto attach_fail3;
2146 * Setup rate tables for all potential media types.
2148 ath_rate_setup(asc, IEEE80211_MODE_11A);
2149 ath_rate_setup(asc, IEEE80211_MODE_11B);
2150 ath_rate_setup(asc, IEEE80211_MODE_11G);
2151 ath_rate_setup(asc, IEEE80211_MODE_TURBO_A);
2153 /* Setup here so ath_rate_update is happy */
2154 ath_setcurmode(asc, IEEE80211_MODE_11A);
2156 err = ath_desc_alloc(devinfo, asc);
2157 if (err != DDI_SUCCESS) {
2158 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2159 "failed to allocate descriptors: %d\n", err));
2160 goto attach_fail3;
2163 if ((asc->asc_tq = ddi_taskq_create(devinfo, "ath_taskq", 1,
2164 TASKQ_DEFAULTPRI, 0)) == NULL) {
2165 goto attach_fail4;
2167 /* Setup transmit queues in the HAL */
2168 if (ath_txq_setup(asc))
2169 goto attach_fail4;
2171 ATH_HAL_GETMAC(ah, ic->ic_macaddr);
2174 * Initialize pointers to device specific functions which
2175 * will be used by the generic layer.
2177 /* 11g support is identified when we fetch the channel set */
2178 if (asc->asc_have11g)
2179 ic->ic_caps |= IEEE80211_C_SHPREAMBLE |
2180 IEEE80211_C_SHSLOT; /* short slot time */
2182 * Query the hal to figure out h/w crypto support.
2184 if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_WEP))
2185 ic->ic_caps |= IEEE80211_C_WEP;
2186 if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_AES_OCB))
2187 ic->ic_caps |= IEEE80211_C_AES;
2188 if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_AES_CCM)) {
2189 ATH_DEBUG((ATH_DBG_ATTACH, "Atheros support H/W CCMP\n"));
2190 ic->ic_caps |= IEEE80211_C_AES_CCM;
2192 if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_CKIP))
2193 ic->ic_caps |= IEEE80211_C_CKIP;
2194 if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_TKIP)) {
2195 ATH_DEBUG((ATH_DBG_ATTACH, "Atheros support H/W TKIP\n"));
2196 ic->ic_caps |= IEEE80211_C_TKIP;
2198 * Check if h/w does the MIC and/or whether the
2199 * separate key cache entries are required to
2200 * handle both tx+rx MIC keys.
2202 if (ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_MIC)) {
2203 ATH_DEBUG((ATH_DBG_ATTACH, "Support H/W TKIP MIC\n"));
2204 ic->ic_caps |= IEEE80211_C_TKIPMIC;
2208 * If the h/w supports storing tx+rx MIC keys
2209 * in one cache slot automatically enable use.
2211 if (ATH_HAL_HASTKIPSPLIT(ah) ||
2212 !ATH_HAL_SETTKIPSPLIT(ah, AH_FALSE)) {
2213 asc->asc_splitmic = 1;
2216 ic->ic_caps |= IEEE80211_C_WPA; /* Support WPA/WPA2 */
2218 asc->asc_hasclrkey = ATH_HAL_CIPHERSUPPORTED(ah, HAL_CIPHER_CLR);
2220 * Mark key cache slots associated with global keys
2221 * as in use. If we knew TKIP was not to be used we
2222 * could leave the +32, +64, and +32+64 slots free.
2224 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2225 setbit(asc->asc_keymap, i);
2226 setbit(asc->asc_keymap, i+64);
2227 if (asc->asc_splitmic) {
2228 setbit(asc->asc_keymap, i+32);
2229 setbit(asc->asc_keymap, i+32+64);
2233 ic->ic_phytype = IEEE80211_T_OFDM;
2234 ic->ic_opmode = IEEE80211_M_STA;
2235 ic->ic_state = IEEE80211_S_INIT;
2236 ic->ic_maxrssi = ATH_MAX_RSSI;
2237 ic->ic_set_shortslot = ath_set_shortslot;
2238 ic->ic_xmit = ath_xmit;
2239 ieee80211_attach(ic);
2241 /* different instance has different WPA door */
2242 (void) snprintf(ic->ic_wpadoor, MAX_IEEE80211STR, "%s_%s%d", WPA_DOOR,
2243 ddi_driver_name(devinfo),
2244 ddi_get_instance(devinfo));
2246 /* Override 80211 default routines */
2247 ic->ic_reset = ath_reset;
2248 asc->asc_newstate = ic->ic_newstate;
2249 ic->ic_newstate = ath_newstate;
2250 ic->ic_watchdog = ath_watchdog;
2251 ic->ic_node_alloc = ath_node_alloc;
2252 ic->ic_node_free = ath_node_free;
2253 ic->ic_crypto.cs_key_alloc = ath_key_alloc;
2254 ic->ic_crypto.cs_key_delete = ath_key_delete;
2255 ic->ic_crypto.cs_key_set = ath_key_set;
2256 ieee80211_media_init(ic);
2258 * initialize default tx key
2260 ic->ic_def_txkey = 0;
2262 asc->asc_rx_pend = 0;
2263 ATH_HAL_INTRSET(ah, 0);
2264 err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW,
2265 &asc->asc_softint_id, NULL, 0, ath_softint_handler, (caddr_t)asc);
2266 if (err != DDI_SUCCESS) {
2267 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2268 "ddi_add_softintr() failed\n"));
2269 goto attach_fail5;
2272 if (ddi_get_iblock_cookie(devinfo, 0, &asc->asc_iblock)
2273 != DDI_SUCCESS) {
2274 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2275 "Can not get iblock cookie for INT\n"));
2276 goto attach_fail6;
2279 if (ddi_add_intr(devinfo, 0, NULL, NULL, ath_intr,
2280 (caddr_t)asc) != DDI_SUCCESS) {
2281 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2282 "Can not set intr for ATH driver\n"));
2283 goto attach_fail6;
2287 * Provide initial settings for the WiFi plugin; whenever this
2288 * information changes, we need to call mac_plugindata_update()
2290 wd.wd_opmode = ic->ic_opmode;
2291 wd.wd_secalloc = WIFI_SEC_NONE;
2292 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
2294 if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
2295 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2296 "MAC version mismatch\n"));
2297 goto attach_fail7;
2300 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI;
2301 macp->m_driver = asc;
2302 macp->m_dip = devinfo;
2303 macp->m_src_addr = ic->ic_macaddr;
2304 macp->m_callbacks = &ath_m_callbacks;
2305 macp->m_min_sdu = 0;
2306 macp->m_max_sdu = IEEE80211_MTU;
2307 macp->m_pdata = &wd;
2308 macp->m_pdata_size = sizeof (wd);
2310 err = mac_register(macp, &ic->ic_mach);
2311 mac_free(macp);
2312 if (err != 0) {
2313 ATH_DEBUG((ATH_DBG_ATTACH, "ath: ath_attach(): "
2314 "mac_register err %x\n", err));
2315 goto attach_fail7;
2318 /* Create minor node of type DDI_NT_NET_WIFI */
2319 (void) snprintf(strbuf, sizeof (strbuf), "%s%d",
2320 ATH_NODENAME, instance);
2321 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
2322 instance + 1, DDI_NT_NET_WIFI, 0);
2323 if (err != DDI_SUCCESS)
2324 ATH_DEBUG((ATH_DBG_ATTACH, "WARN: ath: ath_attach(): "
2325 "Create minor node failed - %d\n", err));
2327 mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
2328 asc->asc_invalid = 1;
2329 asc->asc_isrunning = 0;
2330 asc->asc_promisc = B_FALSE;
2331 bzero(asc->asc_mcast_refs, sizeof (asc->asc_mcast_refs));
2332 bzero(asc->asc_mcast_hash, sizeof (asc->asc_mcast_hash));
2333 return (DDI_SUCCESS);
2334 attach_fail7:
2335 ddi_remove_intr(devinfo, 0, asc->asc_iblock);
2336 attach_fail6:
2337 ddi_remove_softintr(asc->asc_softint_id);
2338 attach_fail5:
2339 (void) ieee80211_detach(ic);
2340 attach_fail4:
2341 ath_desc_free(asc);
2342 if (asc->asc_tq)
2343 ddi_taskq_destroy(asc->asc_tq);
2344 attach_fail3:
2345 ah->ah_detach(asc->asc_ah);
2346 attach_fail2:
2347 ddi_regs_map_free(&asc->asc_io_handle);
2348 attach_fail1:
2349 pci_config_teardown(&asc->asc_cfg_handle);
2350 attach_fail0:
2351 asc->asc_invalid = 1;
2352 mutex_destroy(&asc->asc_txbuflock);
2353 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
2354 if (ATH_TXQ_SETUP(asc, i)) {
2355 struct ath_txq *txq = &asc->asc_txq[i];
2356 mutex_destroy(&txq->axq_lock);
2359 mutex_destroy(&asc->asc_rxbuflock);
2360 mutex_destroy(&asc->asc_genlock);
2361 mutex_destroy(&asc->asc_resched_lock);
2362 ddi_soft_state_free(ath_soft_state_p, instance);
2364 return (DDI_FAILURE);
2368 * Suspend transmit/receive for powerdown
2370 static int
2371 ath_suspend(ath_t *asc)
2373 ATH_LOCK(asc);
2374 ath_stop_locked(asc);
2375 ATH_UNLOCK(asc);
2376 ATH_DEBUG((ATH_DBG_SUSPEND, "ath: suspended.\n"));
2378 return (DDI_SUCCESS);
2381 static int32_t
2382 ath_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
2384 ath_t *asc;
2386 asc = ddi_get_soft_state(ath_soft_state_p, ddi_get_instance(devinfo));
2387 ASSERT(asc != NULL);
2389 switch (cmd) {
2390 case DDI_DETACH:
2391 break;
2393 case DDI_SUSPEND:
2394 return (ath_suspend(asc));
2396 default:
2397 return (DDI_FAILURE);
2400 if (mac_disable(asc->asc_isc.ic_mach) != 0)
2401 return (DDI_FAILURE);
2403 ath_stop_scantimer(asc);
2405 /* disable interrupts */
2406 ATH_HAL_INTRSET(asc->asc_ah, 0);
2409 * Unregister from the MAC layer subsystem
2411 (void) mac_unregister(asc->asc_isc.ic_mach);
2413 /* free intterrupt resources */
2414 ddi_remove_intr(devinfo, 0, asc->asc_iblock);
2415 ddi_remove_softintr(asc->asc_softint_id);
2418 * NB: the order of these is important:
2419 * o call the 802.11 layer before detaching the hal to
2420 * insure callbacks into the driver to delete global
2421 * key cache entries can be handled
2422 * o reclaim the tx queue data structures after calling
2423 * the 802.11 layer as we'll get called back to reclaim
2424 * node state and potentially want to use them
2425 * o to cleanup the tx queues the hal is called, so detach
2426 * it last
2428 ieee80211_detach(&asc->asc_isc);
2429 ath_desc_free(asc);
2430 ddi_taskq_destroy(asc->asc_tq);
2431 ath_txq_cleanup(asc);
2432 asc->asc_ah->ah_detach(asc->asc_ah);
2434 /* free io handle */
2435 ddi_regs_map_free(&asc->asc_io_handle);
2436 pci_config_teardown(&asc->asc_cfg_handle);
2438 /* destroy locks */
2439 mutex_destroy(&asc->asc_rxbuflock);
2440 mutex_destroy(&asc->asc_genlock);
2441 mutex_destroy(&asc->asc_resched_lock);
2443 ddi_remove_minor_node(devinfo, NULL);
2444 ddi_soft_state_free(ath_soft_state_p, ddi_get_instance(devinfo));
2446 return (DDI_SUCCESS);
2450 * quiesce(9E) entry point.
2452 * This function is called when the system is single-threaded at high
2453 * PIL with preemption disabled. Therefore, this function must not be
2454 * blocked.
2456 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
2457 * DDI_FAILURE indicates an error condition and should almost never happen.
2459 static int32_t
2460 ath_quiesce(dev_info_t *devinfo)
2462 ath_t *asc;
2463 struct ath_hal *ah;
2464 int i;
2466 asc = ddi_get_soft_state(ath_soft_state_p, ddi_get_instance(devinfo));
2468 if (asc == NULL || (ah = asc->asc_ah) == NULL)
2469 return (DDI_FAILURE);
2472 * Disable interrupts
2474 ATH_HAL_INTRSET(ah, 0);
2477 * Disable TX HW
2479 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
2480 if (ATH_TXQ_SETUP(asc, i)) {
2481 ATH_HAL_STOPTXDMA(ah, asc->asc_txq[i].axq_qnum);
2486 * Disable RX HW
2488 ATH_HAL_STOPPCURECV(ah);
2489 ATH_HAL_SETRXFILTER(ah, 0);
2490 ATH_HAL_STOPDMARECV(ah);
2491 drv_usecwait(3000);
2494 * Power down HW
2496 ATH_HAL_PHYDISABLE(ah);
2498 return (DDI_SUCCESS);
2501 DDI_DEFINE_STREAM_OPS(ath_dev_ops, nulldev, nulldev, ath_attach, ath_detach,
2502 nodev, NULL, D_MP, NULL, ath_quiesce);
2504 static struct modldrv ath_modldrv = {
2505 &mod_driverops, /* Type of module. This one is a driver */
2506 "ath driver 1.4/HAL 0.10.5.6", /* short description */
2507 &ath_dev_ops /* driver specific ops */
2510 static struct modlinkage modlinkage = {
2511 MODREV_1, (void *)&ath_modldrv, NULL
2516 _info(struct modinfo *modinfop)
2518 return (mod_info(&modlinkage, modinfop));
2522 _init(void)
2524 int status;
2526 status = ddi_soft_state_init(&ath_soft_state_p, sizeof (ath_t), 1);
2527 if (status != 0)
2528 return (status);
2530 mutex_init(&ath_loglock, NULL, MUTEX_DRIVER, NULL);
2531 ath_halfix_init();
2532 mac_init_ops(&ath_dev_ops, "ath");
2533 status = mod_install(&modlinkage);
2534 if (status != 0) {
2535 mac_fini_ops(&ath_dev_ops);
2536 ath_halfix_finit();
2537 mutex_destroy(&ath_loglock);
2538 ddi_soft_state_fini(&ath_soft_state_p);
2541 return (status);
2545 _fini(void)
2547 int status;
2549 status = mod_remove(&modlinkage);
2550 if (status == 0) {
2551 mac_fini_ops(&ath_dev_ops);
2552 ath_halfix_finit();
2553 mutex_destroy(&ath_loglock);
2554 ddi_soft_state_fini(&ath_soft_state_p);
2556 return (status);