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