1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2004 David Young. All rights reserved. 8 * 9 * This code was written by David Young. 10 * 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 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the author nor the names of any co-contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 26 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 27 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 34 * OF SUCH DAMAGE. 35 */ 36 #include <sys/sysmacros.h> 37 #include <sys/pci.h> 38 #include <sys/stat.h> 39 #include <sys/strsubr.h> 40 #include <sys/strsun.h> 41 #include <sys/mac_provider.h> 42 #include <sys/mac_wifi.h> 43 #include <sys/net80211.h> 44 #include "rtwreg.h" 45 #include "rtwvar.h" 46 #include "smc93cx6var.h" 47 #include "rtwphy.h" 48 #include "rtwphyio.h" 49 50 /* 51 * PIO access attributes for registers 52 */ 53 static ddi_device_acc_attr_t rtw_reg_accattr = { 54 DDI_DEVICE_ATTR_V0, 55 DDI_STRUCTURE_LE_ACC, 56 DDI_STRICTORDER_ACC, 57 DDI_DEFAULT_ACC 58 }; 59 60 /* 61 * DMA access attributes for descriptors and bufs: NOT to be byte swapped. 62 */ 63 static ddi_device_acc_attr_t rtw_desc_accattr = { 64 DDI_DEVICE_ATTR_V0, 65 DDI_NEVERSWAP_ACC, 66 DDI_STRICTORDER_ACC, 67 DDI_DEFAULT_ACC 68 }; 69 static ddi_device_acc_attr_t rtw_buf_accattr = { 70 DDI_DEVICE_ATTR_V0, 71 DDI_NEVERSWAP_ACC, 72 DDI_STRICTORDER_ACC, 73 DDI_DEFAULT_ACC 74 }; 75 76 /* 77 * Describes the chip's DMA engine 78 */ 79 static ddi_dma_attr_t dma_attr_desc = { 80 DMA_ATTR_V0, /* dma_attr version */ 81 0x0000000000000000ull, /* dma_attr_addr_lo */ 82 0xFFFFFFFF, /* dma_attr_addr_hi */ 83 0x00000000FFFFFFFFull, /* dma_attr_count_max */ 84 0x100, /* dma_attr_align */ 85 0xFFFFFFFF, /* dma_attr_burstsizes */ 86 0x00000001, /* dma_attr_minxfer */ 87 0x00000000FFFFull, /* dma_attr_maxxfer */ 88 0xFFFFFFFFFFFFFFFFull, /* dma_attr_seg */ 89 1, /* dma_attr_sgllen */ 90 1, /* dma_attr_granular */ 91 0 /* dma_attr_flags */ 92 }; 93 94 static ddi_dma_attr_t dma_attr_rxbuf = { 95 DMA_ATTR_V0, /* dma_attr version */ 96 0x0000000000000000ull, /* dma_attr_addr_lo */ 97 0xFFFFFFFF, /* dma_attr_addr_hi */ 98 0x00000000FFFFFFFFull, /* dma_attr_count_max */ 99 (uint32_t)16, /* dma_attr_align */ 100 0xFFFFFFFF, /* dma_attr_burstsizes */ 101 0x00000001, /* dma_attr_minxfer */ 102 0x00000000FFFFull, /* dma_attr_maxxfer */ 103 0xFFFFFFFFFFFFFFFFull, /* dma_attr_seg */ 104 1, /* dma_attr_sgllen */ 105 1, /* dma_attr_granular */ 106 0 /* dma_attr_flags */ 107 }; 108 109 static ddi_dma_attr_t dma_attr_txbuf = { 110 DMA_ATTR_V0, /* dma_attr version */ 111 0x0000000000000000ull, /* dma_attr_addr_lo */ 112 0xFFFFFFFF, /* dma_attr_addr_hi */ 113 0x00000000FFFFFFFFull, /* dma_attr_count_max */ 114 (uint32_t)16, /* dma_attr_align */ 115 0xFFFFFFFF, /* dma_attr_burstsizes */ 116 0x00000001, /* dma_attr_minxfer */ 117 0x00000000FFFFull, /* dma_attr_maxxfer */ 118 0xFFFFFFFFFFFFFFFFull, /* dma_attr_seg */ 119 1, /* dma_attr_sgllen */ 120 1, /* dma_attr_granular */ 121 0 /* dma_attr_flags */ 122 }; 123 124 125 static void *rtw_soft_state_p = NULL; 126 127 static void rtw_stop(void *); 128 static int rtw_attach(dev_info_t *, ddi_attach_cmd_t); 129 static int rtw_detach(dev_info_t *, ddi_detach_cmd_t); 130 static int rtw_quiesce(dev_info_t *); 131 static int rtw_m_stat(void *, uint_t, uint64_t *); 132 static int rtw_m_start(void *); 133 static void rtw_m_stop(void *); 134 static int rtw_m_promisc(void *, boolean_t); 135 static int rtw_m_multicst(void *, boolean_t, const uint8_t *); 136 static int rtw_m_unicst(void *, const uint8_t *); 137 static mblk_t *rtw_m_tx(void *, mblk_t *); 138 static void rtw_m_ioctl(void *, queue_t *, mblk_t *); 139 static int rtw_m_setprop(void *, const char *, mac_prop_id_t, 140 uint_t, const void *); 141 static int rtw_m_getprop(void *, const char *, mac_prop_id_t, 142 uint_t, uint_t, void *, uint_t *); 143 144 static mac_callbacks_t rtw_m_callbacks = { 145 MC_IOCTL | MC_SETPROP | MC_GETPROP, 146 rtw_m_stat, 147 rtw_m_start, 148 rtw_m_stop, 149 rtw_m_promisc, 150 rtw_m_multicst, 151 rtw_m_unicst, 152 rtw_m_tx, 153 rtw_m_ioctl, 154 NULL, /* mc_getcapab */ 155 NULL, 156 NULL, 157 rtw_m_setprop, 158 rtw_m_getprop 159 }; 160 161 DDI_DEFINE_STREAM_OPS(rtw_dev_ops, nulldev, nulldev, rtw_attach, rtw_detach, 162 nodev, NULL, D_MP, NULL, rtw_quiesce); 163 164 static struct modldrv rtw_modldrv = { 165 &mod_driverops, /* Type of module. This one is a driver */ 166 "realtek 8180L driver 1.7", /* short description */ 167 &rtw_dev_ops /* driver specific ops */ 168 }; 169 170 static struct modlinkage modlinkage = { 171 MODREV_1, (void *)&rtw_modldrv, NULL 172 }; 173 174 static uint32_t rtw_qlen[RTW_NTXPRI] = { 175 RTW_TXQLENLO, 176 RTW_TXQLENMD, 177 RTW_TXQLENHI, 178 RTW_TXQLENBCN 179 }; 180 181 uint32_t rtw_dbg_flags = 0; 182 /* 183 * RTW_DEBUG_ATTACH | RTW_DEBUG_TUNE | 184 * RTW_DEBUG_ACCESS | RTW_DEBUG_INIT | RTW_DEBUG_PKTFILT | 185 * RTW_DEBUG_RECV | RTW_DEBUG_XMIT | RTW_DEBUG_80211 | RTW_DEBUG_INTR | 186 * RTW_DEBUG_PKTDUMP; 187 */ 188 189 /* 190 * Supported rates for 802.11b modes (in 500Kbps unit). 191 */ 192 static const struct ieee80211_rateset rtw_rateset_11b = 193 { 4, { 2, 4, 11, 22 } }; 194 195 int 196 _info(struct modinfo *modinfop) 197 { 198 return (mod_info(&modlinkage, modinfop)); 199 } 200 201 int 202 _init(void) 203 { 204 int status; 205 206 status = ddi_soft_state_init(&rtw_soft_state_p, 207 sizeof (rtw_softc_t), 1); 208 if (status != 0) 209 return (status); 210 211 mac_init_ops(&rtw_dev_ops, "rtw"); 212 status = mod_install(&modlinkage); 213 if (status != 0) { 214 mac_fini_ops(&rtw_dev_ops); 215 ddi_soft_state_fini(&rtw_soft_state_p); 216 } 217 return (status); 218 } 219 220 int 221 _fini(void) 222 { 223 int status; 224 225 status = mod_remove(&modlinkage); 226 if (status == 0) { 227 mac_fini_ops(&rtw_dev_ops); 228 ddi_soft_state_fini(&rtw_soft_state_p); 229 } 230 return (status); 231 } 232 233 void 234 rtw_dbg(uint32_t dbg_flags, const int8_t *fmt, ...) 235 { 236 va_list args; 237 238 if (dbg_flags & rtw_dbg_flags) { 239 va_start(args, fmt); 240 vcmn_err(CE_CONT, fmt, args); 241 va_end(args); 242 } 243 } 244 245 #ifdef DEBUG 246 static void 247 rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where) 248 { 249 #define PRINTREG32(sc, reg) \ 250 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 251 "%s: reg[ " #reg " / %03x ] = %08x\n", \ 252 dvname, reg, RTW_READ(regs, reg)) 253 254 #define PRINTREG16(sc, reg) \ 255 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 256 "%s: reg[ " #reg " / %03x ] = %04x\n", \ 257 dvname, reg, RTW_READ16(regs, reg)) 258 259 #define PRINTREG8(sc, reg) \ 260 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 261 "%s: reg[ " #reg " / %03x ] = %02x\n", \ 262 dvname, reg, RTW_READ8(regs, reg)) 263 264 RTW_DPRINTF(RTW_DEBUG_REGDUMP, "%s: %s\n", dvname, where); 265 266 PRINTREG32(regs, RTW_IDR0); 267 PRINTREG32(regs, RTW_IDR1); 268 PRINTREG32(regs, RTW_MAR0); 269 PRINTREG32(regs, RTW_MAR1); 270 PRINTREG32(regs, RTW_TSFTRL); 271 PRINTREG32(regs, RTW_TSFTRH); 272 PRINTREG32(regs, RTW_TLPDA); 273 PRINTREG32(regs, RTW_TNPDA); 274 PRINTREG32(regs, RTW_THPDA); 275 PRINTREG32(regs, RTW_TCR); 276 PRINTREG32(regs, RTW_RCR); 277 PRINTREG32(regs, RTW_TINT); 278 PRINTREG32(regs, RTW_TBDA); 279 PRINTREG32(regs, RTW_ANAPARM); 280 PRINTREG32(regs, RTW_BB); 281 PRINTREG32(regs, RTW_PHYCFG); 282 PRINTREG32(regs, RTW_WAKEUP0L); 283 PRINTREG32(regs, RTW_WAKEUP0H); 284 PRINTREG32(regs, RTW_WAKEUP1L); 285 PRINTREG32(regs, RTW_WAKEUP1H); 286 PRINTREG32(regs, RTW_WAKEUP2LL); 287 PRINTREG32(regs, RTW_WAKEUP2LH); 288 PRINTREG32(regs, RTW_WAKEUP2HL); 289 PRINTREG32(regs, RTW_WAKEUP2HH); 290 PRINTREG32(regs, RTW_WAKEUP3LL); 291 PRINTREG32(regs, RTW_WAKEUP3LH); 292 PRINTREG32(regs, RTW_WAKEUP3HL); 293 PRINTREG32(regs, RTW_WAKEUP3HH); 294 PRINTREG32(regs, RTW_WAKEUP4LL); 295 PRINTREG32(regs, RTW_WAKEUP4LH); 296 PRINTREG32(regs, RTW_WAKEUP4HL); 297 PRINTREG32(regs, RTW_WAKEUP4HH); 298 PRINTREG32(regs, RTW_DK0); 299 PRINTREG32(regs, RTW_DK1); 300 PRINTREG32(regs, RTW_DK2); 301 PRINTREG32(regs, RTW_DK3); 302 PRINTREG32(regs, RTW_RETRYCTR); 303 PRINTREG32(regs, RTW_RDSAR); 304 PRINTREG32(regs, RTW_FER); 305 PRINTREG32(regs, RTW_FEMR); 306 PRINTREG32(regs, RTW_FPSR); 307 PRINTREG32(regs, RTW_FFER); 308 309 /* 16-bit registers */ 310 PRINTREG16(regs, RTW_BRSR); 311 PRINTREG16(regs, RTW_IMR); 312 PRINTREG16(regs, RTW_ISR); 313 PRINTREG16(regs, RTW_BCNITV); 314 PRINTREG16(regs, RTW_ATIMWND); 315 PRINTREG16(regs, RTW_BINTRITV); 316 PRINTREG16(regs, RTW_ATIMTRITV); 317 PRINTREG16(regs, RTW_CRC16ERR); 318 PRINTREG16(regs, RTW_CRC0); 319 PRINTREG16(regs, RTW_CRC1); 320 PRINTREG16(regs, RTW_CRC2); 321 PRINTREG16(regs, RTW_CRC3); 322 PRINTREG16(regs, RTW_CRC4); 323 PRINTREG16(regs, RTW_CWR); 324 325 /* 8-bit registers */ 326 PRINTREG8(regs, RTW_CR); 327 PRINTREG8(regs, RTW_9346CR); 328 PRINTREG8(regs, RTW_CONFIG0); 329 PRINTREG8(regs, RTW_CONFIG1); 330 PRINTREG8(regs, RTW_CONFIG2); 331 PRINTREG8(regs, RTW_MSR); 332 PRINTREG8(regs, RTW_CONFIG3); 333 PRINTREG8(regs, RTW_CONFIG4); 334 PRINTREG8(regs, RTW_TESTR); 335 PRINTREG8(regs, RTW_PSR); 336 PRINTREG8(regs, RTW_SCR); 337 PRINTREG8(regs, RTW_PHYDELAY); 338 PRINTREG8(regs, RTW_CRCOUNT); 339 PRINTREG8(regs, RTW_PHYADDR); 340 PRINTREG8(regs, RTW_PHYDATAW); 341 PRINTREG8(regs, RTW_PHYDATAR); 342 PRINTREG8(regs, RTW_CONFIG5); 343 PRINTREG8(regs, RTW_TPPOLL); 344 345 PRINTREG16(regs, RTW_BSSID16); 346 PRINTREG32(regs, RTW_BSSID32); 347 #undef PRINTREG32 348 #undef PRINTREG16 349 #undef PRINTREG8 350 } 351 352 #endif /* DEBUG */ 353 static const char * 354 rtw_access_string(enum rtw_access access) 355 { 356 switch (access) { 357 case RTW_ACCESS_NONE: 358 return ("none"); 359 case RTW_ACCESS_CONFIG: 360 return ("config"); 361 case RTW_ACCESS_ANAPARM: 362 return ("anaparm"); 363 default: 364 return ("unknown"); 365 } 366 } 367 368 /* 369 * Enable registers, switch register banks. 370 */ 371 void 372 rtw_config0123_enable(struct rtw_regs *regs, int enable) 373 { 374 uint8_t ecr; 375 ecr = RTW_READ8(regs, RTW_9346CR); 376 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 377 if (enable) 378 ecr |= RTW_9346CR_EEM_CONFIG; 379 else { 380 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3)); 381 ecr |= RTW_9346CR_EEM_NORMAL; 382 } 383 RTW_WRITE8(regs, RTW_9346CR, ecr); 384 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 385 } 386 387 /* 388 * requires rtw_config0123_enable(, 1) 389 */ 390 void 391 rtw_anaparm_enable(struct rtw_regs *regs, int enable) 392 { 393 uint8_t cfg3; 394 395 cfg3 = RTW_READ8(regs, RTW_CONFIG3); 396 cfg3 |= RTW_CONFIG3_CLKRUNEN; 397 if (enable) 398 cfg3 |= RTW_CONFIG3_PARMEN; 399 else 400 cfg3 &= ~RTW_CONFIG3_PARMEN; 401 RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 402 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 403 } 404 405 /* 406 * requires rtw_anaparm_enable(, 1) 407 */ 408 void 409 rtw_txdac_enable(rtw_softc_t *rsc, int enable) 410 { 411 uint32_t anaparm; 412 struct rtw_regs *regs = &rsc->sc_regs; 413 414 anaparm = RTW_READ(regs, RTW_ANAPARM); 415 if (enable) 416 anaparm &= ~RTW_ANAPARM_TXDACOFF; 417 else 418 anaparm |= RTW_ANAPARM_TXDACOFF; 419 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 420 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 421 } 422 423 static void 424 rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess) 425 { 426 ASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM); 427 ASSERT(regs->r_access >= RTW_ACCESS_NONE && 428 regs->r_access <= RTW_ACCESS_ANAPARM); 429 430 if (naccess == regs->r_access) 431 return; 432 433 switch (naccess) { 434 case RTW_ACCESS_NONE: 435 switch (regs->r_access) { 436 case RTW_ACCESS_ANAPARM: 437 rtw_anaparm_enable(regs, 0); 438 /*FALLTHROUGH*/ 439 case RTW_ACCESS_CONFIG: 440 rtw_config0123_enable(regs, 0); 441 /*FALLTHROUGH*/ 442 case RTW_ACCESS_NONE: 443 break; 444 } 445 break; 446 case RTW_ACCESS_CONFIG: 447 switch (regs->r_access) { 448 case RTW_ACCESS_NONE: 449 rtw_config0123_enable(regs, 1); 450 /*FALLTHROUGH*/ 451 case RTW_ACCESS_CONFIG: 452 break; 453 case RTW_ACCESS_ANAPARM: 454 rtw_anaparm_enable(regs, 0); 455 break; 456 } 457 break; 458 case RTW_ACCESS_ANAPARM: 459 switch (regs->r_access) { 460 case RTW_ACCESS_NONE: 461 rtw_config0123_enable(regs, 1); 462 /*FALLTHROUGH*/ 463 case RTW_ACCESS_CONFIG: 464 rtw_anaparm_enable(regs, 1); 465 /*FALLTHROUGH*/ 466 case RTW_ACCESS_ANAPARM: 467 break; 468 } 469 break; 470 } 471 } 472 473 void 474 rtw_set_access(struct rtw_regs *regs, enum rtw_access access) 475 { 476 rtw_set_access1(regs, access); 477 RTW_DPRINTF(RTW_DEBUG_ACCESS, 478 "%s: access %s -> %s\n", __func__, 479 rtw_access_string(regs->r_access), 480 rtw_access_string(access)); 481 regs->r_access = access; 482 } 483 484 485 void 486 rtw_continuous_tx_enable(rtw_softc_t *rsc, int enable) 487 { 488 struct rtw_regs *regs = &rsc->sc_regs; 489 490 uint32_t tcr; 491 tcr = RTW_READ(regs, RTW_TCR); 492 tcr &= ~RTW_TCR_LBK_MASK; 493 if (enable) 494 tcr |= RTW_TCR_LBK_CONT; 495 else 496 tcr |= RTW_TCR_LBK_NORMAL; 497 RTW_WRITE(regs, RTW_TCR, tcr); 498 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 499 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 500 rtw_txdac_enable(rsc, !enable); 501 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 502 rtw_set_access(regs, RTW_ACCESS_NONE); 503 } 504 505 static int 506 rtw_chip_reset1(struct rtw_regs *regs, const char *dvname) 507 { 508 uint8_t cr; 509 int i; 510 511 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 512 513 RTW_WBR(regs, RTW_CR, RTW_CR); 514 515 for (i = 0; i < 1000; i++) { 516 cr = RTW_READ8(regs, RTW_CR); 517 if ((cr & RTW_CR_RST) == 0) { 518 RTW_DPRINTF(RTW_DEBUG_RESET, 519 "%s: reset in %dus\n", dvname, i); 520 return (0); 521 } 522 RTW_RBR(regs, RTW_CR, RTW_CR); 523 DELAY(10); /* 10us */ 524 } 525 526 cmn_err(CE_WARN, "%s: reset failed\n", dvname); 527 return (ETIMEDOUT); 528 } 529 530 static int 531 rtw_chip_reset(struct rtw_regs *regs, const char *dvname) 532 { 533 RTW_WBW(regs, RTW_CR, RTW_TCR); 534 return (rtw_chip_reset1(regs, dvname)); 535 } 536 537 static void 538 rtw_disable_interrupts(struct rtw_regs *regs) 539 { 540 RTW_WRITE16(regs, RTW_IMR, 0); 541 RTW_WRITE16(regs, RTW_ISR, 0xffff); 542 (void) RTW_READ16(regs, RTW_IMR); 543 } 544 545 static void 546 rtw_enable_interrupts(rtw_softc_t *rsc) 547 { 548 struct rtw_regs *regs = &rsc->sc_regs; 549 550 rsc->sc_inten = RTW_INTR_RX | RTW_INTR_TX | RTW_INTR_IOERROR; 551 552 RTW_WRITE16(regs, RTW_IMR, rsc->sc_inten); 553 RTW_WRITE16(regs, RTW_ISR, 0xffff); 554 555 /* XXX necessary? */ 556 if (rsc->sc_intr_ack != NULL) 557 (*rsc->sc_intr_ack)(regs); 558 } 559 560 static int 561 rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname) 562 { 563 int i; 564 uint8_t ecr; 565 566 ecr = RTW_READ8(regs, RTW_9346CR); 567 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 568 RTW_WRITE8(regs, RTW_9346CR, ecr); 569 570 RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 571 572 /* wait 25ms for completion */ 573 for (i = 0; i < 250; i++) { 574 ecr = RTW_READ8(regs, RTW_9346CR); 575 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 576 RTW_DPRINTF(RTW_DEBUG_RESET, 577 "%s: recall EEPROM in %dus\n", dvname, i * 100); 578 return (0); 579 } 580 RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 581 DELAY(100); 582 } 583 cmn_err(CE_WARN, "%s: recall EEPROM failed\n", dvname); 584 return (ETIMEDOUT); 585 } 586 587 static int 588 rtw_reset(rtw_softc_t *rsc) 589 { 590 int rc; 591 592 rc = rtw_chip_reset(&rsc->sc_regs, "rtw"); 593 if (rc != 0) 594 return (rc); 595 596 (void) rtw_recall_eeprom(&rsc->sc_regs, "rtw"); 597 return (0); 598 } 599 600 void 601 rtw_set_mode(struct rtw_regs *regs, int mode) 602 { 603 uint8_t command; 604 command = RTW_READ8(regs, RTW_9346CR); 605 command = command &~ RTW_EPROM_CMD_OPERATING_MODE_MASK; 606 command = command | (mode<<RTW_EPROM_CMD_OPERATING_MODE_SHIFT); 607 command = command &~ (1<<RTW_EPROM_CS_SHIFT); 608 command = command &~ (1<<RTW_EPROM_CK_SHIFT); 609 RTW_WRITE8(regs, RTW_9346CR, command); 610 } 611 612 void 613 rtw_dma_start(struct rtw_regs *regs, int priority) 614 { 615 uint8_t check = 0; 616 617 check = RTW_READ8(regs, RTW_TPPOLL); 618 switch (priority) { 619 case (0): 620 RTW_WRITE8(regs, RTW_TPPOLL, 621 (1<< RTW_TX_DMA_POLLING_LOWPRIORITY_SHIFT) | check); 622 break; 623 case (1): 624 RTW_WRITE8(regs, RTW_TPPOLL, 625 (1<< RTW_TX_DMA_POLLING_NORMPRIORITY_SHIFT) | check); 626 break; 627 case (2): 628 RTW_WRITE8(regs, RTW_TPPOLL, 629 (1<< RTW_TX_DMA_POLLING_HIPRIORITY_SHIFT) | check); 630 break; 631 } 632 (void) RTW_READ8(regs, RTW_TPPOLL); 633 } 634 635 void 636 rtw_beacon_tx_disable(struct rtw_regs *regs) 637 { 638 uint8_t mask = 0; 639 mask |= (1 << RTW_TX_DMA_STOP_BEACON_SHIFT); 640 rtw_set_mode(regs, RTW_EPROM_CMD_CONFIG); 641 RTW_WRITE8(regs, RTW_TPPOLL, mask); 642 rtw_set_mode(regs, RTW_EPROM_CMD_NORMAL); 643 } 644 645 static void 646 rtw_io_enable(rtw_softc_t *rsc, uint8_t flags, int enable); 647 648 void 649 rtw_rtx_disable(rtw_softc_t *rsc) 650 { 651 struct rtw_regs *regs = &rsc->sc_regs; 652 653 rtw_io_enable(rsc, RTW_CR_RE|RTW_CR_TE, 0); 654 (void) RTW_READ8(regs, RTW_CR); 655 } 656 657 static void 658 rtw_srom_free(struct rtw_srom *sr) 659 { 660 if (sr->sr_content == NULL) 661 return; 662 kmem_free(sr->sr_content, sr->sr_size); 663 sr->sr_size = 0; 664 sr->sr_content = NULL; 665 } 666 667 /*ARGSUSED*/ 668 static void 669 rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold, 670 enum rtw_rfchipid *rfchipid, uint32_t *rcr) 671 { 672 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV); 673 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 674 *rcr |= RTW_RCR_ENCS1; 675 *rfchipid = RTW_RFCHIPID_PHILIPS; 676 } 677 678 static int 679 rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold, 680 enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale, 681 const char *dvname) 682 { 683 int i; 684 const char *rfname, *paname; 685 char scratch[sizeof ("unknown 0xXX")]; 686 uint16_t version; 687 uint8_t mac[IEEE80211_ADDR_LEN]; 688 689 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV); 690 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 691 692 version = RTW_SR_GET16(sr, RTW_SR_VERSION); 693 RTW_DPRINTF(RTW_DEBUG_IOSTATE, "%s: SROM version %d.%d", dvname, 694 version >> 8, version & 0xff); 695 696 if (version <= 0x0101) { 697 cmn_err(CE_NOTE, " is not understood, limping along " 698 "with defaults\n"); 699 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr); 700 return (0); 701 } 702 703 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 704 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 705 706 RTW_DPRINTF(RTW_DEBUG_ATTACH, 707 "%s: EEPROM MAC %s\n", dvname, mac); 708 709 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 710 711 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0) 712 *flags |= RTW_F_ANTDIV; 713 714 /* 715 * Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems 716 * to be reversed. 717 */ 718 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0) 719 *flags |= RTW_F_DIGPHY; 720 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 721 *flags |= RTW_F_DFLANTB; 722 723 *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM), 724 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 725 726 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 727 switch (*rfchipid) { 728 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 729 rfname = "GCT GRF5101"; 730 paname = "Winspring WS9901"; 731 break; 732 case RTW_RFCHIPID_MAXIM: 733 rfname = "Maxim MAX2820"; /* guess */ 734 paname = "Maxim MAX2422"; /* guess */ 735 break; 736 case RTW_RFCHIPID_INTERSIL: 737 rfname = "Intersil HFA3873"; /* guess */ 738 paname = "Intersil <unknown>"; 739 break; 740 case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */ 741 rfname = "Philips SA2400A"; 742 paname = "Philips SA2411"; 743 break; 744 case RTW_RFCHIPID_RFMD: 745 /* 746 * this is the same front-end as an atw(4)! 747 */ 748 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 749 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 750 "SYN: Silicon Labs Si4126"; 751 paname = "RFMD RF2189"; /* mentioned in Realtek docs */ 752 break; 753 case RTW_RFCHIPID_RESERVED: 754 rfname = paname = "reserved"; 755 break; 756 default: 757 (void) snprintf(scratch, sizeof (scratch), 758 "unknown 0x%02x", *rfchipid); 759 rfname = paname = scratch; 760 } 761 RTW_DPRINTF(RTW_DEBUG_PHY, "%s: RF: %s, PA: %s\n", 762 dvname, rfname, paname); 763 764 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) { 765 case RTW_CONFIG0_GL_USA: 766 *locale = RTW_LOCALE_USA; 767 break; 768 case RTW_CONFIG0_GL_EUROPE: 769 *locale = RTW_LOCALE_EUROPE; 770 break; 771 case RTW_CONFIG0_GL_JAPAN: 772 *locale = RTW_LOCALE_JAPAN; 773 break; 774 default: 775 *locale = RTW_LOCALE_UNKNOWN; 776 break; 777 } 778 return (0); 779 } 780 781 /* 782 * Returns -1 on failure. 783 */ 784 static int 785 rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr, 786 const char *dvname) 787 { 788 int rc; 789 struct seeprom_descriptor sd; 790 uint8_t ecr; 791 792 (void) memset(&sd, 0, sizeof (sd)); 793 794 ecr = RTW_READ8(regs, RTW_9346CR); 795 796 if ((flags & RTW_F_9356SROM) != 0) { 797 RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: 93c56 SROM\n", dvname); 798 sr->sr_size = 256; 799 sd.sd_chip = C56_66; 800 } else { 801 RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: 93c46 SROM\n", dvname); 802 sr->sr_size = 128; 803 sd.sd_chip = C46; 804 } 805 806 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 807 RTW_9346CR_EEM_MASK | RTW_9346CR_EECS); 808 ecr |= RTW_9346CR_EEM_PROGRAM; 809 810 RTW_WRITE8(regs, RTW_9346CR, ecr); 811 812 sr->sr_content = kmem_zalloc(sr->sr_size, KM_SLEEP); 813 814 if (sr->sr_content == NULL) { 815 cmn_err(CE_WARN, "%s: unable to allocate SROM buffer\n", 816 dvname); 817 return (ENOMEM); 818 } 819 820 (void) memset(sr->sr_content, 0, sr->sr_size); 821 822 /* 823 * RTL8180 has a single 8-bit register for controlling the 824 * 93cx6 SROM. There is no "ready" bit. The RTL8180 825 * input/output sense is the reverse of read_seeprom's. 826 */ 827 sd.sd_handle = regs->r_handle; 828 sd.sd_base = regs->r_base; 829 sd.sd_regsize = 1; 830 sd.sd_control_offset = RTW_9346CR; 831 sd.sd_status_offset = RTW_9346CR; 832 sd.sd_dataout_offset = RTW_9346CR; 833 sd.sd_CK = RTW_9346CR_EESK; 834 sd.sd_CS = RTW_9346CR_EECS; 835 sd.sd_DI = RTW_9346CR_EEDO; 836 sd.sd_DO = RTW_9346CR_EEDI; 837 /* 838 * make read_seeprom enter EEPROM read/write mode 839 */ 840 sd.sd_MS = ecr; 841 sd.sd_RDY = 0; 842 843 /* 844 * TBD bus barriers 845 */ 846 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 847 cmn_err(CE_WARN, "%s: could not read SROM\n", dvname); 848 kmem_free(sr->sr_content, sr->sr_size); 849 sr->sr_content = NULL; 850 return (-1); /* XXX */ 851 } 852 853 /* 854 * end EEPROM read/write mode 855 */ 856 RTW_WRITE8(regs, RTW_9346CR, 857 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 858 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 859 860 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 861 return (rc); 862 863 #ifdef SROM_DEBUG 864 { 865 int i; 866 RTW_DPRINTF(RTW_DEBUG_ATTACH, 867 "\n%s: serial ROM:\n\t", dvname); 868 for (i = 0; i < sr->sr_size/2; i++) { 869 RTW_DPRINTF(RTW_DEBUG_ATTACH, 870 "offset-0x%x: %04x", 2*i, sr->sr_content[i]); 871 } 872 } 873 #endif /* DEBUG */ 874 return (0); 875 } 876 877 static void 878 rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid, 879 const char *dvname) 880 { 881 uint8_t cfg4; 882 const char *method; 883 884 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 885 886 switch (rfchipid) { 887 default: 888 cfg4 |= LSHIFT(0, RTW_CONFIG4_RFTYPE_MASK); 889 method = "fallback"; 890 break; 891 case RTW_RFCHIPID_INTERSIL: 892 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 893 method = "Intersil"; 894 break; 895 case RTW_RFCHIPID_PHILIPS: 896 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 897 method = "Philips"; 898 break; 899 case RTW_RFCHIPID_GCT: /* XXX a guess */ 900 case RTW_RFCHIPID_RFMD: 901 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 902 method = "RFMD"; 903 break; 904 } 905 906 RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 907 908 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 909 910 RTW_DPRINTF(RTW_DEBUG_INIT, 911 "%s: %s RF programming method, %02x\n", dvname, method, 912 RTW_READ8(regs, RTW_CONFIG4)); 913 } 914 915 static void 916 rtw_init_channels(enum rtw_locale locale, 917 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], 918 const char *dvname) 919 { 920 int i; 921 const char *name = NULL; 922 #define ADD_CHANNEL(_chans, _chan) { \ 923 (*_chans)[_chan].ich_flags = IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK;\ 924 (*_chans)[_chan].ich_freq = \ 925 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ich_flags);\ 926 } 927 928 switch (locale) { 929 case RTW_LOCALE_USA: /* 1-11 */ 930 name = "USA"; 931 for (i = 1; i <= 11; i++) 932 ADD_CHANNEL(chans, i); 933 break; 934 case RTW_LOCALE_JAPAN: /* 1-14 */ 935 name = "Japan"; 936 ADD_CHANNEL(chans, 14); 937 for (i = 1; i <= 14; i++) 938 ADD_CHANNEL(chans, i); 939 break; 940 case RTW_LOCALE_EUROPE: /* 1-13 */ 941 name = "Europe"; 942 for (i = 1; i <= 13; i++) 943 ADD_CHANNEL(chans, i); 944 break; 945 default: /* 10-11 allowed by most countries */ 946 name = "<unknown>"; 947 for (i = 10; i <= 11; i++) 948 ADD_CHANNEL(chans, i); 949 break; 950 } 951 RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: Geographic Location %s\n", 952 dvname, name); 953 #undef ADD_CHANNEL 954 } 955 956 static void 957 rtw_set80211props(struct ieee80211com *ic) 958 { 959 ic->ic_phytype = IEEE80211_T_DS; 960 ic->ic_opmode = IEEE80211_M_STA; 961 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 962 IEEE80211_C_SHPREAMBLE; 963 /* IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP */ 964 965 ic->ic_sup_rates[IEEE80211_MODE_11B] = rtw_rateset_11b; 966 } 967 968 /*ARGSUSED*/ 969 static void 970 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale, 971 const char *dvname) 972 { 973 uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 974 975 switch (cfg0 & RTW_CONFIG0_GL_MASK) { 976 case RTW_CONFIG0_GL_USA: 977 *locale = RTW_LOCALE_USA; 978 break; 979 case RTW_CONFIG0_GL_JAPAN: 980 *locale = RTW_LOCALE_JAPAN; 981 break; 982 case RTW_CONFIG0_GL_EUROPE: 983 *locale = RTW_LOCALE_EUROPE; 984 break; 985 default: 986 *locale = RTW_LOCALE_UNKNOWN; 987 break; 988 } 989 } 990 991 static int 992 rtw_identify_sta(struct rtw_regs *regs, uint8_t *addr, 993 const char *dvname) 994 { 995 uint32_t idr0 = RTW_READ(regs, RTW_IDR0), 996 idr1 = RTW_READ(regs, RTW_IDR1); 997 998 *addr = MASK_AND_RSHIFT(idr0, BITS(0, 7)); 999 *(addr + 1) = MASK_AND_RSHIFT(idr0, BITS(8, 15)); 1000 *(addr + 2) = MASK_AND_RSHIFT(idr0, BITS(16, 23)); 1001 *(addr + 3) = MASK_AND_RSHIFT(idr0, BITS(24, 31)); 1002 1003 *(addr + 4) = MASK_AND_RSHIFT(idr1, BITS(0, 7)); 1004 *(addr + 5) = MASK_AND_RSHIFT(idr1, BITS(8, 15)); 1005 1006 RTW_DPRINTF(RTW_DEBUG_ATTACH, 1007 "%s: 802.11mac address %x:%x:%x:%x:%x:%x\n", dvname, 1008 *addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5)); 1009 1010 return (0); 1011 } 1012 1013 static uint8_t 1014 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 1015 struct ieee80211_channel *chan) 1016 { 1017 uint32_t idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 1018 return (RTW_SR_GET(sr, idx)); 1019 } 1020 1021 static void 1022 rtw_rxdesc_init(rtw_softc_t *rsc, struct rtw_rxbuf *rbf, int idx, int is_last) 1023 { 1024 uint32_t ctl = 0; 1025 uint8_t *buf = (uint8_t *)rbf->bf_dma.mem_va; 1026 1027 ASSERT(rbf != NULL); 1028 rbf->rxdesc->rd_buf = (rbf->bf_dma.cookie.dmac_address); 1029 bzero(buf, rbf->bf_dma.alength); 1030 RTW_DMA_SYNC(rbf->bf_dma, DDI_DMA_SYNC_FORDEV); 1031 1032 ctl = (rbf->bf_dma.alength & 0xfff) | RTW_RXCTL_OWN; 1033 1034 if (is_last) 1035 ctl |= RTW_RXCTL_EOR; 1036 1037 rbf->rxdesc->rd_ctl = (ctl); 1038 /* sync the mbuf */ 1039 1040 /* sync the descriptor */ 1041 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 1042 RTW_DESC_OFFSET(hd_rx, idx), 1043 sizeof (struct rtw_rxdesc), 1044 DDI_DMA_SYNC_FORDEV); 1045 } 1046 1047 static void 1048 rtw_idle(struct rtw_regs *regs) 1049 { 1050 int active; 1051 1052 /* request stop DMA; wait for packets to stop transmitting. */ 1053 1054 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 1055 1056 for (active = 0; active < 300 && 1057 (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ALL) != 0; active++) 1058 drv_usecwait(10); 1059 } 1060 1061 static void 1062 rtw_io_enable(rtw_softc_t *rsc, uint8_t flags, int enable) 1063 { 1064 uint8_t cr; 1065 struct rtw_regs *regs = &rsc->sc_regs; 1066 1067 RTW_DPRINTF(RTW_DEBUG_IOSTATE, "%s: %s 0x%02x\n", __func__, 1068 enable ? "enable" : "disable", flags); 1069 1070 cr = RTW_READ8(regs, RTW_CR); 1071 1072 /* The receive engine will always start at RDSAR. */ 1073 if (enable && (flags & ~cr & RTW_CR_RE)) { 1074 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 1075 RTW_DESC_OFFSET(hd_rx, 0), 1076 sizeof (struct rtw_rxdesc), 1077 DDI_DMA_SYNC_FORCPU); 1078 rsc->rx_next = 0; 1079 rtw_rxdesc_init(rsc, rsc->rxbuf_h, 0, 0); 1080 } 1081 1082 if (enable) 1083 cr |= flags; 1084 else 1085 cr &= ~flags; 1086 RTW_WRITE8(regs, RTW_CR, cr); 1087 (void) RTW_READ8(regs, RTW_CR); 1088 } 1089 1090 /* 1091 * Allocate an area of memory and a DMA handle for accessing it 1092 */ 1093 static int 1094 rtw_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr, 1095 size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags, 1096 uint_t bind_flags, dma_area_t *dma_p) 1097 { 1098 int err; 1099 1100 /* 1101 * Allocate handle 1102 */ 1103 err = ddi_dma_alloc_handle(devinfo, dma_attr, 1104 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); 1105 if (err != DDI_SUCCESS) 1106 return (DDI_FAILURE); 1107 1108 /* 1109 * Allocate memory 1110 */ 1111 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p, 1112 alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va, 1113 &dma_p->alength, &dma_p->acc_hdl); 1114 if (err != DDI_SUCCESS) 1115 return (DDI_FAILURE); 1116 1117 /* 1118 * Bind the two together 1119 */ 1120 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 1121 dma_p->mem_va, dma_p->alength, bind_flags, 1122 DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies); 1123 if ((dma_p->ncookies != 1) || (err != DDI_DMA_MAPPED)) 1124 return (DDI_FAILURE); 1125 1126 dma_p->nslots = ~0U; 1127 dma_p->size = ~0U; 1128 dma_p->token = ~0U; 1129 dma_p->offset = 0; 1130 return (DDI_SUCCESS); 1131 } 1132 1133 /* 1134 * Free one allocated area of DMAable memory 1135 */ 1136 static void 1137 rtw_free_dma_mem(dma_area_t *dma_p) 1138 { 1139 if (dma_p->dma_hdl != NULL) { 1140 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 1141 if (dma_p->acc_hdl != NULL) { 1142 ddi_dma_mem_free(&dma_p->acc_hdl); 1143 dma_p->acc_hdl = NULL; 1144 } 1145 ddi_dma_free_handle(&dma_p->dma_hdl); 1146 dma_p->ncookies = 0; 1147 dma_p->dma_hdl = NULL; 1148 } 1149 } 1150 1151 static void 1152 rtw_dma_free(rtw_softc_t *rsc) 1153 { 1154 struct rtw_txbuf *txbf; 1155 struct rtw_rxbuf *rxbf; 1156 int i, j; 1157 1158 /* Free TX DMA buffer */ 1159 for (i = 0; i < RTW_NTXPRI; i++) { 1160 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1161 while (txbf != NULL) { 1162 rtw_free_dma_mem(&txbf->bf_dma); 1163 list_remove(&rsc->sc_txq[i].tx_free_list, txbf); 1164 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1165 } 1166 list_destroy(&rsc->sc_txq[i].tx_free_list); 1167 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1168 while (txbf != NULL) { 1169 rtw_free_dma_mem(&txbf->bf_dma); 1170 list_remove(&rsc->sc_txq[i].tx_dirty_list, txbf); 1171 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1172 } 1173 list_destroy(&rsc->sc_txq[i].tx_dirty_list); 1174 1175 if (rsc->sc_txq[i].txbuf_h != NULL) { 1176 kmem_free(rsc->sc_txq[i].txbuf_h, 1177 sizeof (struct rtw_txbuf) * rtw_qlen[i]); 1178 rsc->sc_txq[i].txbuf_h = NULL; 1179 } 1180 } 1181 1182 /* Free RX DMA buffer */ 1183 rxbf = rsc->rxbuf_h; 1184 for (j = 0; j < RTW_RXQLEN; j++) { 1185 rtw_free_dma_mem(&rxbf->bf_dma); 1186 rxbf++; 1187 } 1188 1189 if (rsc->rxbuf_h != NULL) { 1190 kmem_free(rsc->rxbuf_h, 1191 sizeof (struct rtw_rxbuf) * RTW_RXQLEN); 1192 rsc->rxbuf_h = NULL; 1193 } 1194 1195 rtw_free_dma_mem(&rsc->sc_desc_dma); 1196 } 1197 1198 static int 1199 rtw_dma_init(dev_info_t *devinfo, rtw_softc_t *rsc) 1200 { 1201 int i, j, err; 1202 size_t size; 1203 uint32_t buflen; 1204 struct rtw_txdesc *txds; 1205 struct rtw_rxdesc *rxds; 1206 struct rtw_txbuf *txbf; 1207 struct rtw_rxbuf *rxbf; 1208 uint32_t phybaseaddr, ptx[RTW_NTXPRI], prx; 1209 caddr_t virbaseaddr, vtx[RTW_NTXPRI], vrx; 1210 1211 /* DMA buffer size for each TX/RX packet */ 1212 rsc->sc_dmabuf_size = roundup(sizeof (struct ieee80211_frame) + 0x100 + 1213 IEEE80211_MTU + IEEE80211_CRC_LEN + sizeof (struct ieee80211_llc) + 1214 (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + 1215 IEEE80211_WEP_CRCLEN), rsc->sc_cachelsz); 1216 size = sizeof (struct rtw_descs); 1217 err = rtw_alloc_dma_mem(devinfo, &dma_attr_desc, size, 1218 &rtw_desc_accattr, 1219 DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1220 &rsc->sc_desc_dma); 1221 if (err != DDI_SUCCESS) 1222 goto error; 1223 phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address; 1224 virbaseaddr = rsc->sc_desc_dma.mem_va; 1225 ptx[0] = RTW_RING_BASE(phybaseaddr, hd_txlo); 1226 ptx[1] = RTW_RING_BASE(phybaseaddr, hd_txmd); 1227 ptx[2] = RTW_RING_BASE(phybaseaddr, hd_txhi); 1228 ptx[3] = RTW_RING_BASE(phybaseaddr, hd_bcn); 1229 vtx[0] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txlo)); 1230 vtx[1] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txmd)); 1231 vtx[2] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txhi)); 1232 vtx[3] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_bcn)); 1233 for (i = 0; i < RTW_NTXPRI; i++) { 1234 RTW_DPRINTF(RTW_DEBUG_DMA, "p[%d]=%x, v[%d]=%x", i, ptx[i], 1235 i, vtx[i]); 1236 RTW_DPRINTF(RTW_DEBUG_DMA, "ring%d:", i); 1237 list_create(&rsc->sc_txq[i].tx_free_list, 1238 sizeof (struct rtw_txbuf), 1239 offsetof(struct rtw_txbuf, bf_node)); 1240 list_create(&rsc->sc_txq[i].tx_dirty_list, 1241 sizeof (struct rtw_txbuf), 1242 offsetof(struct rtw_txbuf, bf_node)); 1243 /* virtual address of the first descriptor */ 1244 rsc->sc_txq[i].txdesc_h = 1245 (struct rtw_txdesc *)(uintptr_t)vtx[i]; 1246 1247 txds = rsc->sc_txq[i].txdesc_h; 1248 /* allocate data structures to describe TX DMA buffers */ 1249 buflen = sizeof (struct rtw_txbuf) * rtw_qlen[i]; 1250 txbf = (struct rtw_txbuf *)kmem_zalloc(buflen, KM_SLEEP); 1251 rsc->sc_txq[i].txbuf_h = txbf; 1252 for (j = 0; j < rtw_qlen[i]; j++, txbf++, txds++) { 1253 txbf->txdesc = txds; 1254 txbf->bf_daddr = ptx[i] + ((uintptr_t)txds - 1255 (uintptr_t)rsc->sc_txq[i].txdesc_h); 1256 list_insert_tail(&rsc->sc_txq[i].tx_free_list, txbf); 1257 1258 /* alloc DMA memory */ 1259 err = rtw_alloc_dma_mem(devinfo, &dma_attr_txbuf, 1260 rsc->sc_dmabuf_size, 1261 &rtw_buf_accattr, 1262 DDI_DMA_STREAMING, 1263 DDI_DMA_WRITE | DDI_DMA_STREAMING, 1264 &txbf->bf_dma); 1265 if (err != DDI_SUCCESS) 1266 goto error; 1267 RTW_DPRINTF(RTW_DEBUG_DMA, "pbufaddr[%d]=%x", 1268 j, txbf->bf_dma.cookie.dmac_address); 1269 } 1270 } 1271 prx = RTW_RING_BASE(phybaseaddr, hd_rx); 1272 vrx = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_rx)); 1273 /* virtual address of the first descriptor */ 1274 rsc->rxdesc_h = (struct rtw_rxdesc *)(uintptr_t)vrx; 1275 rxds = rsc->rxdesc_h; 1276 1277 /* allocate data structures to describe RX DMA buffers */ 1278 buflen = sizeof (struct rtw_rxbuf) * RTW_RXQLEN; 1279 rxbf = (struct rtw_rxbuf *)kmem_zalloc(buflen, KM_SLEEP); 1280 rsc->rxbuf_h = rxbf; 1281 1282 for (j = 0; j < RTW_RXQLEN; j++, rxbf++, rxds++) { 1283 rxbf->rxdesc = rxds; 1284 rxbf->bf_daddr = 1285 prx + ((uintptr_t)rxds - (uintptr_t)rsc->rxdesc_h); 1286 1287 /* alloc DMA memory */ 1288 err = rtw_alloc_dma_mem(devinfo, &dma_attr_rxbuf, 1289 rsc->sc_dmabuf_size, 1290 &rtw_buf_accattr, 1291 DDI_DMA_STREAMING, DDI_DMA_READ | DDI_DMA_STREAMING, 1292 &rxbf->bf_dma); 1293 if (err != DDI_SUCCESS) 1294 goto error; 1295 } 1296 1297 return (DDI_SUCCESS); 1298 error: 1299 return (DDI_FAILURE); 1300 } 1301 1302 static void 1303 rtw_hwring_setup(rtw_softc_t *rsc) 1304 { 1305 struct rtw_regs *regs = &rsc->sc_regs; 1306 uint32_t phybaseaddr; 1307 1308 phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address; 1309 1310 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(phybaseaddr, hd_rx)); 1311 RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(phybaseaddr, hd_txlo)); 1312 RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(phybaseaddr, hd_txmd)); 1313 RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(phybaseaddr, hd_txhi)); 1314 RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(phybaseaddr, hd_bcn)); 1315 rsc->hw_start = RTW_READ(regs, RTW_TNPDA); 1316 rsc->hw_go = RTW_READ(regs, RTW_TNPDA); 1317 } 1318 1319 static void 1320 rtw_swring_setup(rtw_softc_t *rsc, int flag) 1321 { 1322 int i, j; 1323 int is_last; 1324 struct rtw_txbuf *txbf; 1325 struct rtw_rxbuf *rxbf; 1326 uint32_t phybaseaddr, ptx[RTW_NTXPRI], baddr_desc, taddr_desc; 1327 1328 phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address; 1329 ptx[0] = RTW_RING_BASE(phybaseaddr, hd_txlo); 1330 ptx[1] = RTW_RING_BASE(phybaseaddr, hd_txmd); 1331 ptx[2] = RTW_RING_BASE(phybaseaddr, hd_txhi); 1332 ptx[3] = RTW_RING_BASE(phybaseaddr, hd_bcn); 1333 RTW_DMA_SYNC(rsc->sc_desc_dma, DDI_DMA_SYNC_FORDEV); 1334 /* sync tx desc and tx buf */ 1335 for (i = 0; i < RTW_NTXPRI; i++) { 1336 rsc->sc_txq[i].tx_prod = rsc->sc_txq[i].tx_cons = 0; 1337 rsc->sc_txq[i].tx_nfree = rtw_qlen[i]; 1338 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1339 while (txbf != NULL) { 1340 list_remove(&rsc->sc_txq[i].tx_free_list, txbf); 1341 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1342 } 1343 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1344 while (txbf != NULL) { 1345 list_remove(&rsc->sc_txq[i].tx_dirty_list, txbf); 1346 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1347 } 1348 txbf = rsc->sc_txq[i].txbuf_h; 1349 baddr_desc = ptx[i]; 1350 taddr_desc = baddr_desc + sizeof (struct rtw_txdesc); 1351 for (j = 0; j < rtw_qlen[i]; j++) { 1352 list_insert_tail(&rsc->sc_txq[i].tx_free_list, txbf); 1353 if (j == (rtw_qlen[i] - 1)) { 1354 is_last = 1; 1355 } else { 1356 is_last = 0; 1357 } 1358 1359 if (is_last) { 1360 txbf->txdesc->td_next = baddr_desc; 1361 } else { 1362 txbf->txdesc->td_next = taddr_desc; 1363 } 1364 txbf->next_bf_daddr = txbf->txdesc->td_next; 1365 RTW_DMA_SYNC(txbf->bf_dma, DDI_DMA_SYNC_FORDEV); 1366 txbf->order = j; 1367 txbf++; 1368 taddr_desc += sizeof (struct rtw_txdesc); 1369 } 1370 } 1371 if (!flag) 1372 return; 1373 1374 /* sync rx desc and rx buf */ 1375 rsc->rx_next = 0; 1376 rxbf = rsc->rxbuf_h; 1377 for (j = 0; j < RTW_RXQLEN; j++) { 1378 RTW_DMA_SYNC(rxbf->bf_dma, DDI_DMA_SYNC_FORCPU); 1379 if (j == (RTW_RXQLEN - 1)) 1380 is_last = 1; 1381 else 1382 is_last = 0; 1383 rtw_rxdesc_init(rsc, rxbf, j, is_last); 1384 rxbf++; 1385 } 1386 } 1387 1388 static void 1389 rtw_resume_ticks(rtw_softc_t *rsc) 1390 { 1391 RTW_WRITE(&rsc->sc_regs, RTW_TINT, 0xffffffff); 1392 } 1393 1394 const char * 1395 rtw_pwrstate_string(enum rtw_pwrstate power) 1396 { 1397 switch (power) { 1398 case RTW_ON: 1399 return ("on"); 1400 case RTW_SLEEP: 1401 return ("sleep"); 1402 case RTW_OFF: 1403 return ("off"); 1404 default: 1405 return ("unknown"); 1406 } 1407 } 1408 1409 /* 1410 * XXX For Maxim, I am using the RFMD settings gleaned from the 1411 * reference driver, plus a magic Maxim "ON" value that comes from 1412 * the Realtek document "Windows PG for Rtl8180." 1413 */ 1414 /*ARGSUSED*/ 1415 static void 1416 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1417 int before_rf, int digphy) 1418 { 1419 uint32_t anaparm; 1420 1421 anaparm = RTW_READ(regs, RTW_ANAPARM); 1422 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1423 1424 switch (power) { 1425 case RTW_OFF: 1426 if (before_rf) 1427 return; 1428 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 1429 anaparm |= RTW_ANAPARM_TXDACOFF; 1430 break; 1431 case RTW_SLEEP: 1432 if (!before_rf) 1433 return; 1434 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 1435 anaparm |= RTW_ANAPARM_TXDACOFF; 1436 break; 1437 case RTW_ON: 1438 if (!before_rf) 1439 return; 1440 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 1441 break; 1442 } 1443 RTW_DPRINTF(RTW_DEBUG_PWR, 1444 "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1445 __func__, rtw_pwrstate_string(power), 1446 (before_rf) ? "before" : "after", anaparm); 1447 1448 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1449 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1450 } 1451 1452 /* 1453 * XXX I am using the RFMD settings gleaned from the reference 1454 * driver. They agree 1455 */ 1456 /*ARGSUSED*/ 1457 static void 1458 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1459 int before_rf, int digphy) 1460 { 1461 uint32_t anaparm; 1462 1463 anaparm = RTW_READ(regs, RTW_ANAPARM); 1464 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1465 1466 switch (power) { 1467 case RTW_OFF: 1468 if (before_rf) 1469 return; 1470 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 1471 anaparm |= RTW_ANAPARM_TXDACOFF; 1472 break; 1473 case RTW_SLEEP: 1474 if (!before_rf) 1475 return; 1476 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 1477 anaparm |= RTW_ANAPARM_TXDACOFF; 1478 break; 1479 case RTW_ON: 1480 if (!before_rf) 1481 return; 1482 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 1483 break; 1484 } 1485 RTW_DPRINTF(RTW_DEBUG_PWR, 1486 "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1487 __func__, rtw_pwrstate_string(power), 1488 (before_rf) ? "before" : "after", anaparm); 1489 1490 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1491 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1492 } 1493 1494 static void 1495 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1496 int before_rf, int digphy) 1497 { 1498 uint32_t anaparm; 1499 1500 anaparm = RTW_READ(regs, RTW_ANAPARM); 1501 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1502 1503 switch (power) { 1504 case RTW_OFF: 1505 if (before_rf) 1506 return; 1507 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 1508 anaparm |= RTW_ANAPARM_TXDACOFF; 1509 break; 1510 case RTW_SLEEP: 1511 if (!before_rf) 1512 return; 1513 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 1514 anaparm |= RTW_ANAPARM_TXDACOFF; 1515 break; 1516 case RTW_ON: 1517 if (!before_rf) 1518 return; 1519 if (digphy) { 1520 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 1521 /* XXX guess */ 1522 anaparm |= RTW_ANAPARM_TXDACOFF; 1523 } else 1524 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 1525 break; 1526 } 1527 RTW_DPRINTF(RTW_DEBUG_PWR, 1528 "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1529 __func__, rtw_pwrstate_string(power), 1530 (before_rf) ? "before" : "after", anaparm); 1531 1532 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1533 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1534 } 1535 1536 static void 1537 rtw_pwrstate0(rtw_softc_t *rsc, enum rtw_pwrstate power, int before_rf, 1538 int digphy) 1539 { 1540 struct rtw_regs *regs = &rsc->sc_regs; 1541 1542 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 1543 1544 (*rsc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 1545 1546 rtw_set_access(regs, RTW_ACCESS_NONE); 1547 } 1548 1549 static void 1550 rtw_rf_destroy(struct rtw_rf *rf) 1551 { 1552 (*rf->rf_destroy)(rf); 1553 } 1554 1555 static int 1556 rtw_rf_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 1557 { 1558 return (*rf->rf_pwrstate)(rf, power); 1559 } 1560 1561 static int 1562 rtw_pwrstate(rtw_softc_t *rsc, enum rtw_pwrstate power) 1563 { 1564 int rc; 1565 1566 RTW_DPRINTF(RTW_DEBUG_PWR, 1567 "%s: %s->%s\n", __func__, 1568 rtw_pwrstate_string(rsc->sc_pwrstate), rtw_pwrstate_string(power)); 1569 1570 if (rsc->sc_pwrstate == power) 1571 return (0); 1572 1573 rtw_pwrstate0(rsc, power, 1, rsc->sc_flags & RTW_F_DIGPHY); 1574 rc = rtw_rf_pwrstate(rsc->sc_rf, power); 1575 rtw_pwrstate0(rsc, power, 0, rsc->sc_flags & RTW_F_DIGPHY); 1576 1577 switch (power) { 1578 case RTW_ON: 1579 /* TBD set LEDs */ 1580 break; 1581 case RTW_SLEEP: 1582 /* TBD */ 1583 break; 1584 case RTW_OFF: 1585 /* TBD */ 1586 break; 1587 } 1588 if (rc == 0) 1589 rsc->sc_pwrstate = power; 1590 else 1591 rsc->sc_pwrstate = RTW_OFF; 1592 return (rc); 1593 } 1594 1595 void 1596 rtw_disable(rtw_softc_t *rsc) 1597 { 1598 int rc; 1599 1600 if ((rsc->sc_flags & RTW_F_ENABLED) == 0) 1601 return; 1602 1603 /* turn off PHY */ 1604 if ((rsc->sc_flags & RTW_F_INVALID) == 0 && 1605 (rc = rtw_pwrstate(rsc, RTW_OFF)) != 0) { 1606 cmn_err(CE_WARN, "failed to turn off PHY (%d)\n", rc); 1607 } 1608 1609 if (rsc->sc_disable != NULL) 1610 (*rsc->sc_disable)(rsc); 1611 1612 rsc->sc_flags &= ~RTW_F_ENABLED; 1613 } 1614 1615 int 1616 rtw_enable(rtw_softc_t *rsc) 1617 { 1618 if ((rsc->sc_flags & RTW_F_ENABLED) == 0) { 1619 if (rsc->sc_enable != NULL && (*rsc->sc_enable)(rsc) != 0) { 1620 cmn_err(CE_WARN, "device enable failed\n"); 1621 return (EIO); 1622 } 1623 rsc->sc_flags |= RTW_F_ENABLED; 1624 if (rtw_pwrstate(rsc, RTW_ON) != 0) 1625 cmn_err(CE_WARN, "PHY turn on failed\n"); 1626 } 1627 return (0); 1628 } 1629 1630 static void 1631 rtw_set_nettype(rtw_softc_t *rsc, enum ieee80211_opmode opmode) 1632 { 1633 uint8_t msr; 1634 1635 /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 1636 rtw_set_access(&rsc->sc_regs, RTW_ACCESS_CONFIG); 1637 1638 msr = RTW_READ8(&rsc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 1639 1640 switch (opmode) { 1641 case IEEE80211_M_AHDEMO: 1642 case IEEE80211_M_IBSS: 1643 msr |= RTW_MSR_NETYPE_ADHOC_OK; 1644 break; 1645 case IEEE80211_M_HOSTAP: 1646 msr |= RTW_MSR_NETYPE_AP_OK; 1647 break; 1648 case IEEE80211_M_STA: 1649 msr |= RTW_MSR_NETYPE_INFRA_OK; 1650 break; 1651 } 1652 RTW_WRITE8(&rsc->sc_regs, RTW_MSR, msr); 1653 1654 rtw_set_access(&rsc->sc_regs, RTW_ACCESS_NONE); 1655 } 1656 1657 static void 1658 rtw_pktfilt_load(rtw_softc_t *rsc) 1659 { 1660 struct rtw_regs *regs = &rsc->sc_regs; 1661 struct ieee80211com *ic = &rsc->sc_ic; 1662 1663 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 1664 rsc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK; 1665 rsc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK); 1666 1667 rsc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT; 1668 /* MAC auto-reset PHY (huh?) */ 1669 rsc->sc_rcr |= RTW_RCR_ENMARP; 1670 /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */ 1671 rsc->sc_rcr |= RTW_RCR_RXFTH_WHOLE |RTW_RCR_MXDMA_1024; 1672 1673 switch (ic->ic_opmode) { 1674 case IEEE80211_M_AHDEMO: 1675 case IEEE80211_M_IBSS: 1676 /* receive broadcasts in our BSS */ 1677 rsc->sc_rcr |= RTW_RCR_ADD3; 1678 break; 1679 default: 1680 break; 1681 } 1682 #if 0 1683 /* XXX accept all broadcast if scanning */ 1684 rsc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 1685 #endif 1686 RTW_WRITE(regs, RTW_MAR0, 0xffffffff); 1687 RTW_WRITE(regs, RTW_MAR1, 0xffffffff); 1688 rsc->sc_rcr |= RTW_RCR_AM; 1689 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 1690 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 1691 1692 RTW_DPRINTF(RTW_DEBUG_PKTFILT, 1693 "RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 1694 RTW_READ(regs, RTW_MAR0), 1695 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)); 1696 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 1697 } 1698 1699 static void 1700 rtw_transmit_config(struct rtw_regs *regs) 1701 { 1702 uint32_t tcr; 1703 1704 tcr = RTW_READ(regs, RTW_TCR); 1705 1706 tcr |= RTW_TCR_CWMIN; 1707 tcr &= ~RTW_TCR_MXDMA_MASK; 1708 tcr |= RTW_TCR_MXDMA_1024; 1709 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 1710 tcr &= ~RTW_TCR_LBK_MASK; 1711 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 1712 1713 /* set short/long retry limits */ 1714 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 1715 tcr |= LSHIFT(0x4, RTW_TCR_SRL_MASK) | LSHIFT(0x4, RTW_TCR_LRL_MASK); 1716 1717 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 1718 RTW_WRITE(regs, RTW_TCR, tcr); 1719 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 1720 } 1721 1722 int 1723 rtw_refine_setting(rtw_softc_t *rsc) 1724 { 1725 struct rtw_regs *regs; 1726 int rc = 0; 1727 1728 regs = &rsc->sc_regs; 1729 rc = rtw_reset(rsc); 1730 if (rc != 0) 1731 return (-1); 1732 1733 rtw_beacon_tx_disable(regs); 1734 rtw_io_enable(rsc, RTW_CR_RE|RTW_CR_TE, 1); 1735 rtw_set_mode(regs, RTW_EPROM_CMD_CONFIG); 1736 1737 rtw_transmit_config(regs); 1738 rtw_pktfilt_load(rsc); 1739 rtw_set_access(regs, RTW_ACCESS_CONFIG); 1740 RTW_WRITE(regs, RTW_TINT, 0xffffffff); 1741 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 1742 RTW_WRITE16(regs, RTW_BRSR, 0); 1743 1744 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 1745 rtw_set_access(regs, RTW_ACCESS_NONE); 1746 RTW_WRITE(regs, RTW_FEMR, 0xffff); 1747 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 1748 rtw_set_rfprog(regs, rsc->sc_rfchipid, "rtw"); 1749 1750 RTW_WRITE8(regs, RTW_PHYDELAY, rsc->sc_phydelay); 1751 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 1752 rtw_set_mode(regs, RTW_EPROM_CMD_NORMAL); 1753 return (0); 1754 } 1755 1756 static int 1757 rtw_tune(rtw_softc_t *rsc) 1758 { 1759 struct ieee80211com *ic = &rsc->sc_ic; 1760 uint32_t chan; 1761 int rc; 1762 int antdiv = rsc->sc_flags & RTW_F_ANTDIV, 1763 dflantb = rsc->sc_flags & RTW_F_DFLANTB; 1764 1765 ASSERT(ic->ic_curchan != NULL); 1766 1767 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 1768 RTW_DPRINTF(RTW_DEBUG_TUNE, "rtw: chan no = %x", chan); 1769 1770 if (chan == IEEE80211_CHAN_ANY) { 1771 cmn_err(CE_WARN, "%s: chan == IEEE80211_CHAN_ANY\n", __func__); 1772 return (-1); 1773 } 1774 1775 if (chan == rsc->sc_cur_chan) { 1776 RTW_DPRINTF(RTW_DEBUG_TUNE, 1777 "%s: already tuned chan %d\n", __func__, chan); 1778 return (0); 1779 } 1780 rtw_idle(&rsc->sc_regs); 1781 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 1782 ASSERT((rsc->sc_flags & RTW_F_ENABLED) != 0); 1783 1784 if ((rc = rtw_phy_init(&rsc->sc_regs, rsc->sc_rf, 1785 rtw_chan2txpower(&rsc->sc_srom, ic, ic->ic_curchan), 1786 rsc->sc_csthr, ic->ic_curchan->ich_freq, antdiv, 1787 dflantb, RTW_ON)) != 0) { 1788 /* XXX condition on powersaving */ 1789 cmn_err(CE_NOTE, "phy init failed\n"); 1790 } 1791 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 1); 1792 rtw_resume_ticks(rsc); 1793 rsc->sc_cur_chan = chan; 1794 return (rc); 1795 } 1796 1797 static int 1798 rtw_init(rtw_softc_t *rsc) 1799 { 1800 struct ieee80211com *ic = &rsc->sc_ic; 1801 int rc = 0; 1802 1803 rtw_stop(rsc); 1804 mutex_enter(&rsc->sc_genlock); 1805 if ((rc = rtw_enable(rsc)) != 0) 1806 goto out; 1807 rc = rtw_refine_setting(rsc); 1808 if (rc != 0) { 1809 mutex_exit(&rsc->sc_genlock); 1810 return (rc); 1811 } 1812 rtw_swring_setup(rsc, 1); 1813 rtw_hwring_setup(rsc); 1814 RTW_WRITE16(&rsc->sc_regs, RTW_BSSID16, 0x0); 1815 RTW_WRITE(&rsc->sc_regs, RTW_BSSID32, 0x0); 1816 rtw_enable_interrupts(rsc); 1817 1818 ic->ic_ibss_chan = &ic->ic_sup_channels[1]; 1819 ic->ic_curchan = ic->ic_ibss_chan; 1820 RTW_DPRINTF(RTW_DEBUG_TUNE, "%s: channel %d freq %d flags 0x%04x\n", 1821 __func__, ieee80211_chan2ieee(ic, ic->ic_curchan), 1822 ic->ic_curchan->ich_freq, ic->ic_curchan->ich_flags); 1823 rsc->sc_invalid = 0; 1824 out: 1825 mutex_exit(&rsc->sc_genlock); 1826 return (rc); 1827 } 1828 1829 static struct rtw_rf * 1830 rtw_rf_attach(rtw_softc_t *rsc, enum rtw_rfchipid rfchipid, int digphy) 1831 { 1832 rtw_rf_write_t rf_write; 1833 struct rtw_rf *rf; 1834 int rtw_host_rfio; 1835 1836 switch (rfchipid) { 1837 default: 1838 rf_write = rtw_rf_hostwrite; 1839 break; 1840 case RTW_RFCHIPID_INTERSIL: 1841 case RTW_RFCHIPID_PHILIPS: 1842 case RTW_RFCHIPID_GCT: /* XXX a guess */ 1843 case RTW_RFCHIPID_RFMD: 1844 rtw_host_rfio = 1; 1845 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite; 1846 break; 1847 } 1848 1849 switch (rfchipid) { 1850 case RTW_RFCHIPID_MAXIM: 1851 rf = rtw_max2820_create(&rsc->sc_regs, rf_write, 0); 1852 rsc->sc_pwrstate_cb = rtw_maxim_pwrstate; 1853 break; 1854 case RTW_RFCHIPID_PHILIPS: 1855 rf = rtw_sa2400_create(&rsc->sc_regs, rf_write, digphy); 1856 rsc->sc_pwrstate_cb = rtw_philips_pwrstate; 1857 break; 1858 case RTW_RFCHIPID_RFMD: 1859 /* XXX RFMD has no RF constructor */ 1860 rsc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 1861 /*FALLTHROUGH*/ 1862 default: 1863 return (NULL); 1864 } 1865 if (rf != NULL) { 1866 rf->rf_continuous_tx_cb = 1867 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 1868 rf->rf_continuous_tx_arg = (void *)rsc; 1869 } 1870 return (rf); 1871 } 1872 1873 /* 1874 * Revision C and later use a different PHY delay setting than 1875 * revisions A and B. 1876 */ 1877 static uint8_t 1878 rtw_check_phydelay(struct rtw_regs *regs, uint32_t rcr0) 1879 { 1880 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 1881 #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 1882 1883 uint8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY); 1884 1885 RTW_WRITE(regs, RTW_RCR, REVAB); 1886 RTW_WBW(regs, RTW_RCR, RTW_RCR); 1887 RTW_WRITE(regs, RTW_RCR, REVC); 1888 1889 RTW_WBR(regs, RTW_RCR, RTW_RCR); 1890 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 1891 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 1892 1893 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */ 1894 RTW_SYNC(regs, RTW_RCR, RTW_RCR); 1895 1896 return (phydelay); 1897 #undef REVC 1898 } 1899 1900 static void rtw_intr_rx(rtw_softc_t *rsc); 1901 static void rtw_ring_recycling(rtw_softc_t *rsc, uint16_t isr, uint32_t pri); 1902 1903 static int 1904 rtw_get_rate(struct ieee80211com *ic) 1905 { 1906 uint8_t (*rates)[IEEE80211_RATE_MAXSIZE]; 1907 int rate; 1908 1909 rates = &ic->ic_bss->in_rates.ir_rates; 1910 1911 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) 1912 rate = ic->ic_fixed_rate; 1913 else if (ic->ic_state == IEEE80211_S_RUN) 1914 rate = (*rates)[ic->ic_bss->in_txrate]; 1915 else 1916 rate = 0; 1917 return (rate & IEEE80211_RATE_VAL); 1918 } 1919 1920 /* 1921 * Arguments in: 1922 * 1923 * paylen: payload length (no FCS, no WEP header) 1924 * 1925 * hdrlen: header length 1926 * 1927 * rate: MSDU speed, units 500kb/s 1928 * 1929 * flags: IEEE80211_F_SHPREAMBLE (use short preamble), 1930 * IEEE80211_F_SHSLOT (use short slot length) 1931 * 1932 * Arguments out: 1933 * 1934 * d: 802.11 Duration field for RTS, 1935 * 802.11 Duration field for data frame, 1936 * PLCP Length for data frame, 1937 * residual octets at end of data slot 1938 */ 1939 static int 1940 rtw_compute_duration1(int len, int use_ack, uint32_t flags, int rate, 1941 struct rtw_ieee80211_duration *d) 1942 { 1943 int pre, ctsrate; 1944 uint16_t ack, bitlen, data_dur, remainder; 1945 1946 /* 1947 * RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK 1948 * DATA reserves medium for SIFS | ACK 1949 * 1950 * XXXMYC: no ACK on multicast/broadcast or control packets 1951 */ 1952 1953 bitlen = len * 8; 1954 1955 pre = IEEE80211_DUR_DS_SIFS; 1956 if ((flags & IEEE80211_F_SHPREAMBLE) != 0) 1957 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE + 1958 IEEE80211_DUR_DS_FAST_PLCPHDR; 1959 else 1960 pre += IEEE80211_DUR_DS_LONG_PREAMBLE + 1961 IEEE80211_DUR_DS_SLOW_PLCPHDR; 1962 1963 d->d_residue = 0; 1964 data_dur = (bitlen * 2) / rate; 1965 remainder = (bitlen * 2) % rate; 1966 if (remainder != 0) { 1967 if (rate == 22) 1968 d->d_residue = (rate - remainder) / 16; 1969 data_dur++; 1970 } 1971 1972 switch (rate) { 1973 case 2: /* 1 Mb/s */ 1974 case 4: /* 2 Mb/s */ 1975 /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */ 1976 ctsrate = 2; 1977 break; 1978 case 11: /* 5.5 Mb/s */ 1979 case 22: /* 11 Mb/s */ 1980 case 44: /* 22 Mb/s */ 1981 /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */ 1982 ctsrate = 4; 1983 break; 1984 default: 1985 /* TBD */ 1986 return (-1); 1987 } 1988 1989 d->d_plcp_len = data_dur; 1990 1991 ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0; 1992 1993 d->d_rts_dur = 1994 pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate + 1995 pre + data_dur + 1996 ack; 1997 1998 d->d_data_dur = ack; 1999 2000 return (0); 2001 } 2002 2003 /* 2004 * Arguments in: 2005 * 2006 * wh: 802.11 header 2007 * 2008 * paylen: payload length (no FCS, no WEP header) 2009 * 2010 * rate: MSDU speed, units 500kb/s 2011 * 2012 * fraglen: fragment length, set to maximum (or higher) for no 2013 * fragmentation 2014 * 2015 * flags: IEEE80211_F_PRIVACY (hardware adds WEP), 2016 * IEEE80211_F_SHPREAMBLE (use short preamble), 2017 * IEEE80211_F_SHSLOT (use short slot length) 2018 * 2019 * Arguments out: 2020 * 2021 * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields 2022 * of first/only fragment 2023 * 2024 * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields 2025 * of first/only fragment 2026 */ 2027 static int 2028 rtw_compute_duration(struct ieee80211_frame *wh, int len, 2029 uint32_t flags, int fraglen, int rate, struct rtw_ieee80211_duration *d0, 2030 struct rtw_ieee80211_duration *dn, int *npktp) 2031 { 2032 int ack, rc; 2033 int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen; 2034 2035 /* don't think about addr4 here */ 2036 hdrlen = sizeof (struct ieee80211_frame); 2037 2038 paylen = len - hdrlen; 2039 2040 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) { 2041 overlen = 8 + IEEE80211_CRC_LEN; 2042 paylen -= 8; 2043 } else 2044 overlen = IEEE80211_CRC_LEN; 2045 2046 npkt = paylen / fraglen; 2047 lastlen0 = paylen % fraglen; 2048 2049 if (npkt == 0) /* no fragments */ 2050 lastlen = paylen + overlen; 2051 else if (lastlen0 != 0) { /* a short "tail" fragment */ 2052 lastlen = lastlen0 + overlen; 2053 npkt++; 2054 } else /* full-length "tail" fragment */ 2055 lastlen = fraglen + overlen; 2056 2057 if (npktp != NULL) 2058 *npktp = npkt; 2059 2060 if (npkt > 1) 2061 firstlen = fraglen + overlen; 2062 else 2063 firstlen = paylen + overlen; 2064 2065 ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) && 2066 (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != 2067 IEEE80211_FC0_TYPE_CTL; 2068 2069 rc = rtw_compute_duration1(firstlen + hdrlen, 2070 ack, flags, rate, d0); 2071 if (rc == -1) 2072 return (rc); 2073 2074 if (npkt <= 1) { 2075 *dn = *d0; 2076 return (0); 2077 } 2078 return (rtw_compute_duration1(lastlen + hdrlen, ack, flags, 2079 rate, dn)); 2080 } 2081 2082 static int 2083 rtw_assembly_80211(rtw_softc_t *rsc, struct rtw_txbuf *bf, 2084 mblk_t *mp) 2085 { 2086 ieee80211com_t *ic; 2087 struct rtw_txdesc *ds; 2088 struct ieee80211_frame *wh; 2089 uint8_t *buf; 2090 uint32_t ctl0 = 0, ctl1 = 0; 2091 int npkt, rate; 2092 struct rtw_ieee80211_duration d0, dn; 2093 int32_t iswep, pktlen, mblen; 2094 mblk_t *mp0; 2095 2096 ic = &rsc->sc_ic; 2097 ds = bf->txdesc; 2098 buf = (uint8_t *)bf->bf_dma.mem_va; 2099 bzero(buf, bf->bf_dma.alength); 2100 bzero((uint8_t *)ds, sizeof (struct rtw_txdesc)); 2101 wh = (struct ieee80211_frame *)mp->b_rptr; 2102 iswep = wh->i_fc[1] & IEEE80211_FC1_WEP; 2103 2104 /* ieee80211_crypto_encap() needs a single mblk */ 2105 mp0 = allocb(bf->bf_dma.alength, BPRI_MED); 2106 if (mp0 == NULL) { 2107 cmn_err(CE_WARN, "%s: allocb(mp) error", __func__); 2108 return (-1); 2109 } 2110 for (; mp != NULL; mp = mp->b_cont) { 2111 mblen = (uintptr_t)mp->b_wptr - (uintptr_t)mp->b_rptr; 2112 bcopy(mp->b_rptr, mp0->b_wptr, mblen); 2113 mp0->b_wptr += mblen; 2114 } 2115 2116 if (iswep) { 2117 struct ieee80211_key *k; 2118 2119 k = ieee80211_crypto_encap(ic, mp0); 2120 if (k == NULL) { 2121 cmn_err(CE_WARN, "%s: ieee80211_crypto_encap() error", 2122 __func__); 2123 freemsg(mp0); 2124 return (-1); 2125 } 2126 } 2127 pktlen = msgdsize(mp0); 2128 2129 #if 0 2130 RTW_DPRINTF(RTW_DEBUG_XMIT, "-----------send------begin--------"); 2131 ieee80211_dump_pkt((uint8_t *)(mp0->b_rptr), pktlen, 0, 0); 2132 RTW_DPRINTF(RTW_DEBUG_XMIT, "-----------send------end--------"); 2133 #endif 2134 /* RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV); */ 2135 if (pktlen > bf->bf_dma.alength) { 2136 cmn_err(CE_WARN, "%s: overlength packet pktlen = %d\n", 2137 __func__, pktlen); 2138 freemsg(mp0); 2139 return (-1); 2140 } 2141 bcopy(mp0->b_rptr, buf, pktlen); 2142 RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV); 2143 2144 /* setup descriptor */ 2145 ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 2146 2147 if (((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) && 2148 (ic->ic_bss->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 2149 ctl0 |= RTW_TXCTL0_SPLCP; 2150 } 2151 /* XXX do real rate control */ 2152 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2153 IEEE80211_FC0_TYPE_MGT) 2154 rate = 2; 2155 else { 2156 rate = MAX(2, rtw_get_rate(ic)); 2157 } 2158 ctl0 = ctl0 | 2159 LSHIFT(pktlen, RTW_TXCTL0_TPKTSIZE_MASK); 2160 2161 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: rate = %d", __func__, rate); 2162 2163 switch (rate) { 2164 default: 2165 case 2: 2166 ctl0 |= RTW_TXCTL0_RATE_1MBPS; 2167 break; 2168 case 4: 2169 ctl0 |= RTW_TXCTL0_RATE_2MBPS; 2170 break; 2171 case 11: 2172 ctl0 |= RTW_TXCTL0_RATE_5MBPS; 2173 break; 2174 case 22: 2175 ctl0 |= RTW_TXCTL0_RATE_11MBPS; 2176 break; 2177 } 2178 2179 /* XXX >= ? Compare after fragmentation? */ 2180 if (pktlen > ic->ic_rtsthreshold) { 2181 ctl0 |= RTW_TXCTL0_RTSEN; 2182 cmn_err(CE_NOTE, "%s: fragmentation: pktlen = %d", 2183 __func__, pktlen); 2184 } 2185 2186 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2187 IEEE80211_FC0_TYPE_MGT) { 2188 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN); 2189 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 2190 IEEE80211_FC0_SUBTYPE_BEACON) 2191 ctl0 |= RTW_TXCTL0_BEACON; 2192 } 2193 2194 if (rtw_compute_duration(wh, pktlen, 2195 ic->ic_flags, ic->ic_fragthreshold, 2196 rate, &d0, &dn, &npkt) == -1) { 2197 RTW_DPRINTF(RTW_DEBUG_XMIT, 2198 "%s: fail compute duration\n", __func__); 2199 freemsg(mp0); 2200 return (-1); 2201 } 2202 *(uint16_t *)(uintptr_t)wh->i_dur = (d0.d_data_dur); 2203 2204 ctl1 = LSHIFT(d0.d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 2205 LSHIFT(d0.d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 2206 2207 if (d0.d_residue) 2208 ctl1 |= RTW_TXCTL1_LENGEXT; 2209 2210 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: duration=%x, ctl1=%x", __func__, 2211 *(uint16_t *)(uintptr_t)wh->i_dur, ctl1); 2212 2213 if (bf->bf_dma.alength > RTW_TXLEN_LENGTH_MASK) { 2214 RTW_DPRINTF(RTW_DEBUG_XMIT, 2215 "%s: seg too long\n", __func__); 2216 freemsg(mp0); 2217 return (-1); 2218 } 2219 ds->td_ctl0 = ctl0; 2220 ds->td_ctl0 |= RTW_TXCTL0_OWN | RTW_TXCTL0_LS | RTW_TXCTL0_FS; 2221 ds->td_ctl1 = ctl1; 2222 ds->td_buf = bf->bf_dma.cookie.dmac_address; 2223 ds->td_len = pktlen & 0xfff; 2224 ds->td_next = bf->next_bf_daddr; 2225 2226 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2227 RTW_DESC_OFFSET(hd_txmd, bf->order), 2228 sizeof (struct rtw_txdesc), 2229 DDI_DMA_SYNC_FORDEV); 2230 2231 RTW_DPRINTF(RTW_DEBUG_XMIT, 2232 "descriptor: order = %d, phy_addr=%x, ctl0=%x," 2233 " ctl1=%x, buf=%x, len=%x, next=%x", bf->order, 2234 bf->bf_daddr, ds->td_ctl0, ds->td_ctl1, 2235 ds->td_buf, ds->td_len, ds->td_next); 2236 rsc->sc_pktxmt64++; 2237 rsc->sc_bytexmt64 += pktlen; 2238 2239 freemsg(mp0); 2240 return (0); 2241 } 2242 2243 static int 2244 rtw_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 2245 { 2246 rtw_softc_t *rsc = (rtw_softc_t *)ic; 2247 struct ieee80211_node *in = ic->ic_bss; 2248 struct rtw_txbuf *bf = NULL; 2249 int ret, i = RTW_TXPRIMD; 2250 2251 mutex_enter(&rsc->sc_txlock); 2252 mutex_enter(&rsc->sc_txq[i].txbuf_lock); 2253 bf = list_head(&rsc->sc_txq[i].tx_free_list); 2254 2255 if ((bf == NULL) || (rsc->sc_txq[i].tx_nfree <= 4)) { 2256 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: no tx buf\n", __func__); 2257 rsc->sc_noxmtbuf++; 2258 if ((type & IEEE80211_FC0_TYPE_MASK) == 2259 IEEE80211_FC0_TYPE_DATA) { 2260 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: need reschedule\n", 2261 __func__); 2262 rsc->sc_need_reschedule = 1; 2263 } else { 2264 freemsg(mp); 2265 } 2266 mutex_exit(&rsc->sc_txq[i].txbuf_lock); 2267 mutex_exit(&rsc->sc_txlock); 2268 return (1); 2269 } 2270 list_remove(&rsc->sc_txq[i].tx_free_list, bf); 2271 rsc->sc_txq[i].tx_nfree--; 2272 2273 /* assemble 802.11 frame here */ 2274 ret = rtw_assembly_80211(rsc, bf, mp); 2275 if (ret != 0) { 2276 cmn_err(CE_WARN, "%s assembly frame error\n", __func__); 2277 mutex_exit(&rsc->sc_txq[i].txbuf_lock); 2278 mutex_exit(&rsc->sc_txlock); 2279 if ((type & IEEE80211_FC0_TYPE_MASK) != 2280 IEEE80211_FC0_TYPE_DATA) { 2281 freemsg(mp); 2282 } 2283 return (1); 2284 } 2285 list_insert_tail(&rsc->sc_txq[i].tx_dirty_list, bf); 2286 bf->bf_in = in; 2287 rtw_dma_start(&rsc->sc_regs, i); 2288 2289 mutex_exit(&rsc->sc_txq[i].txbuf_lock); 2290 mutex_exit(&rsc->sc_txlock); 2291 2292 freemsg(mp); 2293 return (0); 2294 } 2295 2296 static mblk_t * 2297 rtw_m_tx(void *arg, mblk_t *mp) 2298 { 2299 rtw_softc_t *rsc = arg; 2300 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2301 mblk_t *next; 2302 2303 if (ic->ic_state != IEEE80211_S_RUN) { 2304 freemsgchain(mp); 2305 return (NULL); 2306 } 2307 2308 while (mp != NULL) { 2309 next = mp->b_next; 2310 mp->b_next = NULL; 2311 2312 if (rtw_send(ic, mp, IEEE80211_FC0_TYPE_DATA)) { 2313 mp->b_next = next; 2314 break; 2315 } 2316 mp = next; 2317 } 2318 2319 return (mp); 2320 2321 } 2322 2323 static void 2324 rtw_next_scan(void *arg) 2325 { 2326 ieee80211com_t *ic = arg; 2327 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2328 2329 rsc->sc_scan_id = 0; 2330 if (ic->ic_state == IEEE80211_S_SCAN) { 2331 RTW_DPRINTF(RTW_DEBUG_TUNE, "rtw_next_scan\n"); 2332 (void) ieee80211_next_scan(ic); 2333 } 2334 2335 } 2336 2337 static void 2338 rtw_join_bss(rtw_softc_t *rsc, uint8_t *bssid, uint16_t intval0) 2339 { 2340 uint16_t bcnitv, intval; 2341 int i; 2342 struct rtw_regs *regs = &rsc->sc_regs; 2343 2344 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 2345 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 2346 2347 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 2348 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2349 2350 RTW_WRITE8(regs, RTW_MSR, 0x8); /* sta mode link ok */ 2351 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK)); 2352 2353 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 2354 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK); 2355 RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 2356 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND)); 2357 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV)); 2358 2359 rtw_set_access(regs, RTW_ACCESS_NONE); 2360 2361 /* TBD WEP */ 2362 /* RTW_WRITE8(regs, RTW_SCR, 0); */ 2363 2364 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 1); 2365 } 2366 2367 /* 2368 * Set the starting transmit rate for a node. 2369 */ 2370 static void 2371 rtw_rate_ctl_start(rtw_softc_t *rsc, struct ieee80211_node *in) 2372 { 2373 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2374 int32_t srate; 2375 2376 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { 2377 /* 2378 * No fixed rate is requested. For 11b start with 2379 * the highest negotiated rate; otherwise, for 11g 2380 * and 11a, we start "in the middle" at 24Mb or 36Mb. 2381 */ 2382 srate = in->in_rates.ir_nrates - 1; 2383 if (ic->ic_curmode != IEEE80211_MODE_11B) { 2384 /* 2385 * Scan the negotiated rate set to find the 2386 * closest rate. 2387 */ 2388 /* NB: the rate set is assumed sorted */ 2389 for (; srate >= 0 && IEEE80211_RATE(srate) > 72; 2390 srate--) 2391 ; 2392 } 2393 } else { 2394 /* 2395 * A fixed rate is to be used; We know the rate is 2396 * there because the rate set is checked when the 2397 * station associates. 2398 */ 2399 /* NB: the rate set is assumed sorted */ 2400 srate = in->in_rates.ir_nrates - 1; 2401 for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate; 2402 srate--) 2403 ; 2404 } 2405 in->in_txrate = srate; 2406 } 2407 2408 2409 /* 2410 * Reset the rate control state for each 802.11 state transition. 2411 */ 2412 static void 2413 rtw_rate_ctl_reset(rtw_softc_t *rsc, enum ieee80211_state state) 2414 { 2415 ieee80211com_t *ic = &rsc->sc_ic; 2416 ieee80211_node_t *in; 2417 2418 if (ic->ic_opmode == IEEE80211_M_STA) { 2419 /* 2420 * Reset local xmit state; this is really only 2421 * meaningful when operating in station mode. 2422 */ 2423 in = (struct ieee80211_node *)ic->ic_bss; 2424 2425 if (state == IEEE80211_S_RUN) { 2426 rtw_rate_ctl_start(rsc, in); 2427 } else { 2428 in->in_txrate = 0; 2429 } 2430 } 2431 } 2432 2433 /* 2434 * Examine and potentially adjust the transmit rate. 2435 */ 2436 static void 2437 rtw_rate_ctl(void *arg) 2438 { 2439 ieee80211com_t *ic = (ieee80211com_t *)arg; 2440 rtw_softc_t *rsc = (rtw_softc_t *)ic; 2441 struct ieee80211_node *in = ic->ic_bss; 2442 struct ieee80211_rateset *rs = &in->in_rates; 2443 int32_t mod = 1, nrate, enough; 2444 2445 mutex_enter(&rsc->sc_genlock); 2446 enough = (rsc->sc_tx_ok + rsc->sc_tx_err) >= 600? 1 : 0; 2447 2448 /* err ratio is high -> down */ 2449 if (enough && rsc->sc_tx_ok < rsc->sc_tx_err) 2450 mod = -1; 2451 2452 nrate = in->in_txrate; 2453 switch (mod) { 2454 case -1: 2455 if (nrate > 0) { 2456 nrate--; 2457 } 2458 break; 2459 case 1: 2460 if (nrate + 1 < rs->ir_nrates) { 2461 nrate++; 2462 } 2463 break; 2464 } 2465 2466 if (nrate != in->in_txrate) 2467 in->in_txrate = nrate; 2468 rsc->sc_tx_ok = rsc->sc_tx_err = rsc->sc_tx_retr = 0; 2469 mutex_exit(&rsc->sc_genlock); 2470 if (ic->ic_state == IEEE80211_S_RUN) 2471 rsc->sc_ratectl_id = timeout(rtw_rate_ctl, ic, 2472 drv_usectohz(1000000)); 2473 } 2474 2475 static int32_t 2476 rtw_new_state(ieee80211com_t *ic, enum ieee80211_state nstate, int arg) 2477 { 2478 rtw_softc_t *rsc = (rtw_softc_t *)ic; 2479 int error; 2480 enum ieee80211_state ostate; 2481 2482 ostate = ic->ic_state; 2483 2484 RTW_DPRINTF(RTW_DEBUG_ATTACH, 2485 "rtw_new_state: ostate:0x%x, nstate:0x%x, opmode:0x%x\n", 2486 ostate, nstate, ic->ic_opmode); 2487 2488 2489 mutex_enter(&rsc->sc_genlock); 2490 if (rsc->sc_scan_id != 0) { 2491 (void) untimeout(rsc->sc_scan_id); 2492 rsc->sc_scan_id = 0; 2493 } 2494 if (rsc->sc_ratectl_id != 0) { 2495 (void) untimeout(rsc->sc_ratectl_id); 2496 rsc->sc_ratectl_id = 0; 2497 } 2498 rtw_rate_ctl_reset(rsc, nstate); 2499 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 2500 (void) rtw_pwrstate(rsc, RTW_ON); 2501 if (nstate != IEEE80211_S_INIT) { 2502 if ((error = rtw_tune(rsc)) != 0) { 2503 mutex_exit(&rsc->sc_genlock); 2504 return (error); 2505 } 2506 } 2507 switch (nstate) { 2508 case IEEE80211_S_INIT: 2509 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_INIT\n"); 2510 break; 2511 case IEEE80211_S_SCAN: 2512 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_SCAN\n"); 2513 rsc->sc_scan_id = timeout(rtw_next_scan, ic, 2514 drv_usectohz(200000)); 2515 rtw_set_nettype(rsc, IEEE80211_M_MONITOR); 2516 break; 2517 case IEEE80211_S_RUN: 2518 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_RUN\n"); 2519 switch (ic->ic_opmode) { 2520 case IEEE80211_M_HOSTAP: 2521 case IEEE80211_M_IBSS: 2522 rtw_set_nettype(rsc, IEEE80211_M_MONITOR); 2523 /* TBD */ 2524 /*FALLTHROUGH*/ 2525 case IEEE80211_M_AHDEMO: 2526 case IEEE80211_M_STA: 2527 RTW_DPRINTF(RTW_DEBUG_ATTACH, 2528 "rtw_new_state: sta\n"); 2529 rtw_join_bss(rsc, ic->ic_bss->in_bssid, 0); 2530 rsc->sc_ratectl_id = timeout(rtw_rate_ctl, ic, 2531 drv_usectohz(1000000)); 2532 break; 2533 case IEEE80211_M_MONITOR: 2534 break; 2535 } 2536 rtw_set_nettype(rsc, ic->ic_opmode); 2537 break; 2538 case IEEE80211_S_ASSOC: 2539 case IEEE80211_S_AUTH: 2540 break; 2541 } 2542 2543 mutex_exit(&rsc->sc_genlock); 2544 /* 2545 * Invoke the parent method to complete the work. 2546 */ 2547 error = rsc->sc_newstate(ic, nstate, arg); 2548 2549 return (error); 2550 } 2551 2552 static void 2553 rtw_intr_rx(rtw_softc_t *rsc) 2554 { 2555 #define IS_BEACON(__fc0) \ 2556 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\ 2557 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON)) 2558 /* 2559 * ratetbl[4] = {2, 4, 11, 22}; 2560 */ 2561 struct rtw_rxbuf *bf; 2562 struct rtw_rxdesc *ds; 2563 int hwrate, len, rssi; 2564 uint32_t hstat, hrssi, htsftl; 2565 int is_last, next, n = 0, i; 2566 struct ieee80211_frame *wh; 2567 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2568 mblk_t *mp; 2569 2570 RTW_DPRINTF(RTW_DEBUG_RECV, "%s rtw_intr_rx: enter ic_state=%x\n", 2571 __func__, rsc->sc_ic.ic_state); 2572 mutex_enter(&rsc->rxbuf_lock); 2573 next = rsc->rx_next; 2574 mutex_exit(&rsc->rxbuf_lock); 2575 for (i = 0; i < RTW_RXQLEN; i++) { 2576 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2577 RTW_DESC_OFFSET(hd_rx, next), 2578 sizeof (struct rtw_rxdesc), 2579 DDI_DMA_SYNC_FORKERNEL); 2580 n++; 2581 bf = rsc->rxbuf_h + next; 2582 ds = bf->rxdesc; 2583 hstat = (ds->rd_stat); 2584 hrssi = ds->rd_rssi; 2585 htsftl = ds->rd_tsftl; 2586 /* htsfth = ds->rd_tsfth; */ 2587 RTW_DPRINTF(RTW_DEBUG_RECV, "%s: stat=%x\n", __func__, hstat); 2588 /* still belongs to NIC */ 2589 if ((hstat & RTW_RXSTAT_OWN) != 0) { 2590 if (n > 1) { 2591 RTW_DPRINTF(RTW_DEBUG_RECV, 2592 "%s: n > 1\n", __func__); 2593 break; 2594 } 2595 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2596 RTW_DESC_OFFSET(hd_rx, 0), 2597 sizeof (struct rtw_rxdesc), 2598 DDI_DMA_SYNC_FORCPU); 2599 bf = rsc->rxbuf_h; 2600 ds = bf->rxdesc; 2601 hstat = (ds->rd_stat); 2602 if ((hstat & RTW_RXSTAT_OWN) != 0) 2603 break; 2604 next = 0 /* RTW_RXQLEN - 1 */; 2605 continue; 2606 } 2607 2608 rsc->sc_pktrcv64++; 2609 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 2610 RTW_DPRINTF(RTW_DEBUG_RECV, 2611 "rtw: DMA error/FIFO overflow %08x, " 2612 "rx descriptor %d\n", 2613 hstat & RTW_RXSTAT_IOERROR, next); 2614 goto next; 2615 } 2616 2617 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK); 2618 rsc->sc_bytercv64 += len; 2619 2620 /* CRC is included with the packet; trim it off. */ 2621 /* len -= IEEE80211_CRC_LEN; */ 2622 2623 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK); 2624 if (hwrate >= 4) { 2625 goto next; 2626 } 2627 2628 if ((hstat & RTW_RXSTAT_RES) != 0 && 2629 rsc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) { 2630 goto next; 2631 } 2632 2633 /* if bad flags, skip descriptor */ 2634 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 2635 RTW_DPRINTF(RTW_DEBUG_RECV, 2636 "rtw too many rx segments\n"); 2637 goto next; 2638 } 2639 2640 if (rsc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 2641 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI); 2642 else { 2643 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI); 2644 /* 2645 * TBD find out each front-end's LNA gain in the 2646 * front-end's units 2647 */ 2648 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 2649 rssi |= 0x80; 2650 } 2651 /* sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ); */ 2652 2653 2654 /* deal with the frame itself here */ 2655 mp = allocb(rsc->sc_dmabuf_size, BPRI_MED); 2656 if (mp == NULL) { 2657 cmn_err(CE_WARN, "rtw: alloc mblk error"); 2658 rsc->sc_norcvbuf++; 2659 return; 2660 } 2661 len -= IEEE80211_CRC_LEN; 2662 RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORKERNEL); 2663 bcopy(bf->bf_dma.mem_va, mp->b_rptr, len); 2664 mp->b_wptr += len; 2665 wh = (struct ieee80211_frame *)mp->b_rptr; 2666 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2667 IEEE80211_FC0_TYPE_CTL) { 2668 cmn_err(CE_WARN, "TYPE CTL !!\n"); 2669 freemsg(mp); 2670 goto next; 2671 } 2672 (void) ieee80211_input(ic, mp, ic->ic_bss, rssi, htsftl); 2673 next: 2674 if (next == 63) 2675 is_last = 1; 2676 else 2677 is_last = 0; 2678 rtw_rxdesc_init(rsc, bf, next, is_last); 2679 2680 next = (next + 1)%RTW_RXQLEN; 2681 RTW_DPRINTF(RTW_DEBUG_RECV, "%s: next = %d\n", __func__, next); 2682 } 2683 mutex_enter(&rsc->rxbuf_lock); 2684 rsc->rx_next = next; 2685 mutex_exit(&rsc->rxbuf_lock); 2686 } 2687 2688 static void 2689 rtw_ring_recycling(rtw_softc_t *rsc, uint16_t isr, uint32_t pri) 2690 { 2691 struct rtw_txbuf *bf; 2692 struct rtw_txdesc *ds; 2693 uint32_t hstat; 2694 uint32_t head = 0; 2695 uint32_t cnt = 0, idx = 0; 2696 2697 mutex_enter(&rsc->sc_txq[pri].txbuf_lock); 2698 head = RTW_READ(&rsc->sc_regs, RTW_TNPDA); 2699 if (head == rsc->hw_go) { 2700 mutex_exit(&rsc->sc_txq[pri].txbuf_lock); 2701 return; 2702 } 2703 RTW_DPRINTF(RTW_DEBUG_XMIT, "rtw_ring_recycling: enter ic_state=%x\n", 2704 rsc->sc_ic.ic_state); 2705 2706 bf = list_head(&rsc->sc_txq[pri].tx_dirty_list); 2707 if (bf == NULL) { 2708 RTW_DPRINTF(RTW_DEBUG_XMIT, 2709 "rtw_ring_recycling: dirty bf[%d] NULL\n", pri); 2710 mutex_exit(&rsc->sc_txq[pri].txbuf_lock); 2711 return; 2712 } 2713 2714 while ((bf != NULL) && (rsc->hw_go != head)) { 2715 cnt++; 2716 idx = (rsc->hw_go - rsc->hw_start) / sizeof (struct rtw_txdesc); 2717 if (idx == 63) 2718 rsc->hw_go = rsc->hw_start; 2719 else 2720 rsc->hw_go += sizeof (struct rtw_txdesc); 2721 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2722 RTW_DESC_OFFSET(hd_txmd, idx), 2723 sizeof (struct rtw_txdesc), 2724 DDI_DMA_SYNC_FORCPU); 2725 2726 RTW_DPRINTF(RTW_DEBUG_XMIT, "Head = 0x%x\n", head); 2727 ds = bf->txdesc; 2728 hstat = (ds->td_stat); 2729 ds->td_len = ds->td_len & 0xfff; 2730 RTW_DPRINTF(RTW_DEBUG_XMIT, 2731 "%s rtw_ring_recycling: stat=%x, pri=%x\n", 2732 __func__, hstat, pri); 2733 if (hstat & RTW_TXSTAT_TOK) 2734 rsc->sc_tx_ok++; 2735 else { 2736 RTW_DPRINTF(RTW_DEBUG_XMIT, 2737 "TX err @%d, o %d, retry[%d], isr[0x%x], cnt %d\n", 2738 idx, (hstat & RTW_TXSTAT_OWN)?1:0, 2739 (hstat & RTW_TXSTAT_DRC_MASK), isr, cnt); 2740 if ((hstat & RTW_TXSTAT_DRC_MASK) <= 4) { 2741 rsc->sc_tx_ok++; 2742 } else { 2743 rsc->sc_tx_err++; 2744 } 2745 } 2746 rsc->sc_tx_retr += 2747 (hstat & RTW_TXSTAT_DRC_MASK); 2748 rsc->sc_xmtretry += 2749 (hstat & RTW_TXSTAT_DRC_MASK); 2750 list_remove(&rsc->sc_txq[pri].tx_dirty_list, bf); 2751 list_insert_tail(&rsc->sc_txq[pri].tx_free_list, 2752 bf); 2753 (rsc->sc_txq[pri].tx_nfree)++; 2754 if (rsc->sc_need_reschedule == 1) { 2755 mac_tx_update(rsc->sc_ic.ic_mach); 2756 rsc->sc_need_reschedule = 0; 2757 } 2758 RTW_DPRINTF(RTW_DEBUG_XMIT, 2759 "rtw_ring_recycling: nfree[%d]=%d\n", 2760 pri, rsc->sc_txq[pri].tx_nfree); 2761 bzero((uint8_t *)ds, sizeof (struct rtw_txdesc)); 2762 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2763 RTW_DESC_OFFSET(hd_txmd, idx), 2764 sizeof (struct rtw_txdesc), 2765 DDI_DMA_SYNC_FORDEV); 2766 bf = list_head(&rsc->sc_txq[pri].tx_dirty_list); 2767 } 2768 mutex_exit(&rsc->sc_txq[pri].txbuf_lock); 2769 } 2770 2771 static void 2772 rtw_intr_timeout(rtw_softc_t *rsc) 2773 { 2774 rtw_resume_ticks(rsc); 2775 } 2776 2777 static uint_t 2778 rtw_intr(caddr_t arg) 2779 { 2780 /* LINTED E_BAD_PTR_CAST_ALIGN */ 2781 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2782 struct rtw_regs *regs = &rsc->sc_regs; 2783 uint16_t isr = 0; 2784 2785 mutex_enter(&rsc->sc_genlock); 2786 isr = RTW_READ16(regs, RTW_ISR); 2787 RTW_WRITE16(regs, RTW_ISR, isr); 2788 2789 if (isr == 0) { 2790 mutex_exit(&rsc->sc_genlock); 2791 return (DDI_INTR_UNCLAIMED); 2792 } 2793 2794 #ifdef DEBUG 2795 #define PRINTINTR(flag) { \ 2796 if ((isr & flag) != 0) { \ 2797 RTW_DPRINTF(RTW_DEBUG_INTR, "|" #flag); \ 2798 } \ 2799 } 2800 2801 if ((rtw_dbg_flags & RTW_DEBUG_INTR) != 0 && isr != 0) { 2802 2803 RTW_DPRINTF(RTW_DEBUG_INTR, "rtw: reg[ISR] = %x", isr); 2804 2805 PRINTINTR(RTW_INTR_TXFOVW); 2806 PRINTINTR(RTW_INTR_TIMEOUT); 2807 PRINTINTR(RTW_INTR_BCNINT); 2808 PRINTINTR(RTW_INTR_ATIMINT); 2809 PRINTINTR(RTW_INTR_TBDER); 2810 PRINTINTR(RTW_INTR_TBDOK); 2811 PRINTINTR(RTW_INTR_THPDER); 2812 PRINTINTR(RTW_INTR_THPDOK); 2813 PRINTINTR(RTW_INTR_TNPDER); 2814 PRINTINTR(RTW_INTR_TNPDOK); 2815 PRINTINTR(RTW_INTR_RXFOVW); 2816 PRINTINTR(RTW_INTR_RDU); 2817 PRINTINTR(RTW_INTR_TLPDER); 2818 PRINTINTR(RTW_INTR_TLPDOK); 2819 PRINTINTR(RTW_INTR_RER); 2820 PRINTINTR(RTW_INTR_ROK); 2821 } 2822 #undef PRINTINTR 2823 #endif /* DEBUG */ 2824 2825 rsc->sc_intr++; 2826 2827 if ((isr & RTW_INTR_RX) != 0) { 2828 mutex_exit(&rsc->sc_genlock); 2829 rtw_intr_rx(rsc); 2830 mutex_enter(&rsc->sc_genlock); 2831 } 2832 if ((isr & RTW_INTR_TIMEOUT) != 0) 2833 rtw_intr_timeout(rsc); 2834 2835 if ((isr & RTW_INTR_TX) != 0) 2836 rtw_ring_recycling(rsc, isr, 1); 2837 mutex_exit(&rsc->sc_genlock); 2838 return (DDI_INTR_CLAIMED); 2839 } 2840 2841 static void 2842 rtw_stop(void *arg) 2843 { 2844 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2845 struct rtw_regs *regs = &rsc->sc_regs; 2846 2847 mutex_enter(&rsc->sc_genlock); 2848 rtw_disable_interrupts(regs); 2849 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 2850 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 2851 rsc->sc_invalid = 1; 2852 mutex_exit(&rsc->sc_genlock); 2853 } 2854 2855 static void 2856 rtw_m_stop(void *arg) 2857 { 2858 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2859 2860 (void) ieee80211_new_state(&rsc->sc_ic, IEEE80211_S_INIT, -1); 2861 rtw_stop(rsc); 2862 } 2863 2864 /* 2865 * quiesce(9E) entry point. 2866 * 2867 * This function is called when the system is single-threaded at high 2868 * PIL with preemption disabled. Therefore, this function must not be 2869 * blocked. 2870 * 2871 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 2872 * DDI_FAILURE indicates an error condition and should almost never happen. 2873 */ 2874 int 2875 rtw_quiesce(dev_info_t *dip) 2876 { 2877 rtw_softc_t *rsc = NULL; 2878 struct rtw_regs *regs; 2879 2880 rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(dip)); 2881 ASSERT(rsc != NULL); 2882 regs = &rsc->sc_regs; 2883 2884 rtw_dbg_flags = 0; 2885 rtw_disable_interrupts(regs); 2886 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 2887 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 2888 2889 return (DDI_SUCCESS); 2890 } 2891 2892 /* 2893 * callback functions for /get/set properties 2894 */ 2895 static int 2896 rtw_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2897 uint_t wldp_length, const void *wldp_buf) 2898 { 2899 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2900 struct ieee80211com *ic = &rsc->sc_ic; 2901 int err; 2902 2903 err = ieee80211_setprop(ic, pr_name, wldp_pr_num, 2904 wldp_length, wldp_buf); 2905 if (err == ENETRESET) { 2906 if (ic->ic_des_esslen && (rsc->sc_invalid == 0)) { 2907 (void) rtw_init(rsc); 2908 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2909 } 2910 err = 0; 2911 } 2912 return (err); 2913 } 2914 2915 static int 2916 rtw_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2917 uint_t pr_flags, uint_t wldp_length, void *wldp_buf, uint_t *perm) 2918 { 2919 rtw_softc_t *rsc = arg; 2920 int err; 2921 2922 err = ieee80211_getprop(&rsc->sc_ic, pr_name, wldp_pr_num, 2923 pr_flags, wldp_length, wldp_buf, perm); 2924 2925 return (err); 2926 } 2927 2928 2929 static int 2930 rtw_m_start(void *arg) 2931 { 2932 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2933 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2934 int ret; 2935 #ifdef DEBUG 2936 rtw_print_regs(&rsc->sc_regs, "rtw", "rtw_start"); 2937 #endif 2938 2939 ret = rtw_init(rsc); 2940 if (ret) { 2941 cmn_err(CE_WARN, "rtw: failed to do rtw_init\n"); 2942 return (EIO); 2943 } 2944 (void) ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2945 return (0); 2946 } 2947 2948 2949 static int 2950 rtw_m_unicst(void *arg, const uint8_t *macaddr) 2951 { 2952 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2953 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2954 struct rtw_regs *regs = &rsc->sc_regs; 2955 uint32_t t; 2956 2957 mutex_enter(&rsc->sc_genlock); 2958 bcopy(macaddr, ic->ic_macaddr, 6); 2959 t = ((*macaddr)<<24) | ((*(macaddr + 1))<<16) | 2960 ((*(macaddr + 2))<<8) | (*(macaddr + 3)); 2961 RTW_WRITE(regs, RTW_IDR0, ntohl(t)); 2962 t = ((*(macaddr + 4))<<24) | ((*(macaddr + 5))<<16); 2963 RTW_WRITE(regs, RTW_IDR1, ntohl(t)); 2964 mutex_exit(&rsc->sc_genlock); 2965 return (0); 2966 } 2967 2968 static int 2969 rtw_m_promisc(void *arg, boolean_t on) 2970 { 2971 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2972 struct rtw_regs *regs = &rsc->sc_regs; 2973 2974 mutex_enter(&rsc->sc_genlock); 2975 2976 if (on) 2977 rsc->sc_rcr |= RTW_RCR_PROMIC; 2978 else 2979 rsc->sc_rcr &= ~RTW_RCR_PROMIC; 2980 2981 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 2982 2983 mutex_exit(&rsc->sc_genlock); 2984 return (0); 2985 } 2986 2987 static int 2988 rtw_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr) 2989 { 2990 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2991 struct rtw_regs *regs = &rsc->sc_regs; 2992 uint32_t t; 2993 2994 mutex_enter(&rsc->sc_genlock); 2995 if (add) { 2996 rsc->sc_rcr |= RTW_RCR_AM; 2997 t = ((*macaddr)<<24) | ((*(macaddr + 1))<<16) | 2998 ((*(macaddr + 2))<<8) | (*(macaddr + 3)); 2999 RTW_WRITE(regs, RTW_MAR0, ntohl(t)); 3000 t = ((*(macaddr + 4))<<24) | ((*(macaddr + 5))<<16); 3001 RTW_WRITE(regs, RTW_MAR1, ntohl(t)); 3002 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 3003 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); 3004 } else { 3005 rsc->sc_rcr &= ~RTW_RCR_AM; 3006 RTW_WRITE(regs, RTW_MAR0, 0); 3007 RTW_WRITE(regs, RTW_MAR1, 0); 3008 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 3009 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); 3010 } 3011 mutex_exit(&rsc->sc_genlock); 3012 return (0); 3013 } 3014 3015 static void 3016 rtw_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 3017 { 3018 rtw_softc_t *rsc = arg; 3019 struct ieee80211com *ic = &rsc->sc_ic; 3020 int err; 3021 3022 err = ieee80211_ioctl(ic, wq, mp); 3023 if (err == ENETRESET) { 3024 if (ic->ic_des_esslen && (rsc->sc_invalid == 0)) { 3025 (void) rtw_init(rsc); 3026 (void) ieee80211_new_state(ic, 3027 IEEE80211_S_SCAN, -1); 3028 } 3029 } 3030 } 3031 3032 static int 3033 rtw_m_stat(void *arg, uint_t stat, uint64_t *val) 3034 { 3035 rtw_softc_t *rsc = (rtw_softc_t *)arg; 3036 ieee80211com_t *ic = &rsc->sc_ic; 3037 struct ieee80211_node *in = 0; 3038 struct ieee80211_rateset *rs = 0; 3039 3040 mutex_enter(&rsc->sc_genlock); 3041 switch (stat) { 3042 case MAC_STAT_IFSPEED: 3043 in = ic->ic_bss; 3044 rs = &in->in_rates; 3045 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ? 3046 (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) 3047 : ic->ic_fixed_rate) / 2 * 1000000; 3048 break; 3049 case MAC_STAT_NOXMTBUF: 3050 *val = rsc->sc_noxmtbuf; 3051 break; 3052 case MAC_STAT_NORCVBUF: 3053 *val = rsc->sc_norcvbuf; 3054 break; 3055 case MAC_STAT_RBYTES: 3056 *val = rsc->sc_bytercv64; 3057 break; 3058 case MAC_STAT_IPACKETS: 3059 *val = rsc->sc_pktrcv64; 3060 break; 3061 case MAC_STAT_OBYTES: 3062 *val = rsc->sc_bytexmt64; 3063 break; 3064 case MAC_STAT_OPACKETS: 3065 *val = rsc->sc_pktxmt64; 3066 break; 3067 case WIFI_STAT_TX_RETRANS: 3068 *val = rsc->sc_xmtretry; 3069 break; 3070 case WIFI_STAT_TX_FRAGS: 3071 case WIFI_STAT_MCAST_TX: 3072 case WIFI_STAT_RTS_SUCCESS: 3073 case WIFI_STAT_RTS_FAILURE: 3074 case WIFI_STAT_ACK_FAILURE: 3075 case WIFI_STAT_RX_FRAGS: 3076 case WIFI_STAT_MCAST_RX: 3077 case WIFI_STAT_RX_DUPS: 3078 mutex_exit(&rsc->sc_genlock); 3079 return (ieee80211_stat(ic, stat, val)); 3080 default: 3081 *val = 0; 3082 break; 3083 } 3084 mutex_exit(&rsc->sc_genlock); 3085 3086 return (0); 3087 } 3088 3089 3090 static void 3091 rtw_mutex_destroy(rtw_softc_t *rsc) 3092 { 3093 int i; 3094 3095 mutex_destroy(&rsc->rxbuf_lock); 3096 mutex_destroy(&rsc->sc_txlock); 3097 for (i = 0; i < RTW_NTXPRI; i++) { 3098 mutex_destroy(&rsc->sc_txq[RTW_NTXPRI - 1 - i].txbuf_lock); 3099 } 3100 mutex_destroy(&rsc->sc_genlock); 3101 } 3102 3103 static int 3104 rtw_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 3105 { 3106 rtw_softc_t *rsc; 3107 ieee80211com_t *ic; 3108 uint8_t csz; 3109 uint32_t i; 3110 uint16_t vendor_id, device_id, command; 3111 int32_t err; 3112 char strbuf[32]; 3113 wifi_data_t wd = { 0 }; 3114 mac_register_t *macp; 3115 int instance = ddi_get_instance(devinfo); 3116 3117 switch (cmd) { 3118 case DDI_ATTACH: 3119 break; 3120 case DDI_RESUME: 3121 rsc = ddi_get_soft_state(rtw_soft_state_p, 3122 ddi_get_instance(devinfo)); 3123 ASSERT(rsc != NULL); 3124 mutex_enter(&rsc->sc_genlock); 3125 rsc->sc_flags &= ~RTW_F_SUSPEND; 3126 mutex_exit(&rsc->sc_genlock); 3127 if ((rsc->sc_flags & RTW_F_PLUMBED)) { 3128 err = rtw_init(rsc); 3129 if (err == 0) { 3130 mutex_enter(&rsc->sc_genlock); 3131 rsc->sc_flags &= ~RTW_F_PLUMBED; 3132 mutex_exit(&rsc->sc_genlock); 3133 } 3134 } 3135 return (DDI_SUCCESS); 3136 default: 3137 return (DDI_FAILURE); 3138 } 3139 3140 if (ddi_soft_state_zalloc(rtw_soft_state_p, 3141 ddi_get_instance(devinfo)) != DDI_SUCCESS) { 3142 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3143 "Unable to alloc softstate\n"); 3144 return (DDI_FAILURE); 3145 } 3146 3147 rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(devinfo)); 3148 ic = &rsc->sc_ic; 3149 rsc->sc_dev = devinfo; 3150 3151 err = ddi_regs_map_setup(devinfo, 0, (caddr_t *)&rsc->sc_cfg_base, 0, 0, 3152 &rtw_reg_accattr, &rsc->sc_cfg_handle); 3153 if (err != DDI_SUCCESS) { 3154 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3155 "ddi_regs_map_setup() failed"); 3156 goto attach_fail0; 3157 } 3158 csz = ddi_get8(rsc->sc_cfg_handle, 3159 (uint8_t *)(rsc->sc_cfg_base + PCI_CONF_CACHE_LINESZ)); 3160 if (!csz) 3161 csz = 16; 3162 rsc->sc_cachelsz = csz << 2; 3163 vendor_id = ddi_get16(rsc->sc_cfg_handle, 3164 (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_VENID)); 3165 device_id = ddi_get16(rsc->sc_cfg_handle, 3166 (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_DEVID)); 3167 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): vendor 0x%x, " 3168 "device id 0x%x, cache size %d\n", vendor_id, device_id, csz); 3169 3170 /* 3171 * Enable response to memory space accesses, 3172 * and enabe bus master. 3173 */ 3174 command = PCI_COMM_MAE | PCI_COMM_ME; 3175 ddi_put16(rsc->sc_cfg_handle, 3176 (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_COMM), command); 3177 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3178 "set command reg to 0x%x \n", command); 3179 3180 ddi_put8(rsc->sc_cfg_handle, 3181 (uint8_t *)(rsc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8); 3182 3183 ddi_regs_map_free(&rsc->sc_cfg_handle); 3184 3185 err = ddi_regs_map_setup(devinfo, 2, (caddr_t *)&rsc->sc_regs.r_base, 3186 0, 0, &rtw_reg_accattr, &rsc->sc_regs.r_handle); 3187 if (err != DDI_SUCCESS) { 3188 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3189 "ddi_regs_map_setup() failed"); 3190 goto attach_fail0; 3191 } 3192 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: r_base=%x, r_handle=%x\n", 3193 rsc->sc_regs.r_base, rsc->sc_regs.r_handle); 3194 3195 err = rtw_dma_init(devinfo, rsc); 3196 if (err != DDI_SUCCESS) { 3197 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3198 "failed to init dma: %d\n", err); 3199 goto attach_fail1; 3200 } 3201 3202 /* 3203 * Stop the transmit and receive processes. First stop DMA, 3204 * then disable receiver and transmitter. 3205 */ 3206 RTW_WRITE8(&rsc->sc_regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 3207 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 3208 3209 /* Reset the chip to a known state. */ 3210 if (rtw_reset(rsc) != 0) { 3211 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3212 "failed to reset\n"); 3213 goto attach_fail2; 3214 } 3215 rsc->sc_rcr = RTW_READ(&rsc->sc_regs, RTW_RCR); 3216 3217 if ((rsc->sc_rcr & RTW_RCR_9356SEL) != 0) 3218 rsc->sc_flags |= RTW_F_9356SROM; 3219 3220 if (rtw_srom_read(&rsc->sc_regs, rsc->sc_flags, &rsc->sc_srom, 3221 "rtw") != 0) { 3222 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3223 "failed to read srom\n"); 3224 goto attach_fail2; 3225 } 3226 3227 if (rtw_srom_parse(&rsc->sc_srom, &rsc->sc_flags, &rsc->sc_csthr, 3228 &rsc->sc_rfchipid, &rsc->sc_rcr, &rsc->sc_locale, 3229 "rtw") != 0) { 3230 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_attach():" 3231 " malformed serial ROM\n"); 3232 goto attach_fail3; 3233 } 3234 3235 RTW_DPRINTF(RTW_DEBUG_PHY, "rtw: %s PHY\n", 3236 ((rsc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"); 3237 3238 3239 rsc->sc_rf = rtw_rf_attach(rsc, rsc->sc_rfchipid, 3240 rsc->sc_flags & RTW_F_DIGPHY); 3241 3242 if (rsc->sc_rf == NULL) { 3243 cmn_err(CE_WARN, "rtw: rtw_attach(): could not attach RF\n"); 3244 goto attach_fail3; 3245 } 3246 rsc->sc_phydelay = rtw_check_phydelay(&rsc->sc_regs, rsc->sc_rcr); 3247 3248 RTW_DPRINTF(RTW_DEBUG_ATTACH, 3249 "rtw: PHY delay %d\n", rsc->sc_phydelay); 3250 3251 if (rsc->sc_locale == RTW_LOCALE_UNKNOWN) 3252 rtw_identify_country(&rsc->sc_regs, &rsc->sc_locale, 3253 "rtw"); 3254 3255 rtw_init_channels(rsc->sc_locale, &rsc->sc_ic.ic_sup_channels, 3256 "rtw"); 3257 3258 rtw_set80211props(ic); 3259 3260 if (rtw_identify_sta(&rsc->sc_regs, ic->ic_macaddr, 3261 "rtw") != 0) 3262 goto attach_fail4; 3263 3264 ic->ic_xmit = rtw_send; 3265 ieee80211_attach(ic); 3266 3267 rsc->sc_newstate = ic->ic_newstate; 3268 ic->ic_newstate = rtw_new_state; 3269 ieee80211_media_init(ic); 3270 ic->ic_def_txkey = 0; 3271 3272 if (ddi_get_iblock_cookie(devinfo, 0, &(rsc->sc_iblock)) 3273 != DDI_SUCCESS) { 3274 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3275 "Can not get iblock cookie for INT\n"); 3276 goto attach_fail5; 3277 } 3278 3279 mutex_init(&rsc->sc_genlock, NULL, MUTEX_DRIVER, rsc->sc_iblock); 3280 for (i = 0; i < RTW_NTXPRI; i++) { 3281 mutex_init(&rsc->sc_txq[i].txbuf_lock, NULL, MUTEX_DRIVER, 3282 rsc->sc_iblock); 3283 } 3284 mutex_init(&rsc->rxbuf_lock, NULL, MUTEX_DRIVER, rsc->sc_iblock); 3285 mutex_init(&rsc->sc_txlock, NULL, MUTEX_DRIVER, rsc->sc_iblock); 3286 3287 if (ddi_add_intr(devinfo, 0, &rsc->sc_iblock, NULL, rtw_intr, 3288 (caddr_t)(rsc)) != DDI_SUCCESS) { 3289 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3290 "Can not add intr for rtw driver\n"); 3291 goto attach_fail7; 3292 } 3293 3294 /* 3295 * Provide initial settings for the WiFi plugin; whenever this 3296 * information changes, we need to call mac_plugindata_update() 3297 */ 3298 wd.wd_opmode = ic->ic_opmode; 3299 wd.wd_secalloc = WIFI_SEC_NONE; 3300 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid); 3301 3302 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 3303 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3304 "MAC version mismatch\n"); 3305 goto attach_fail8; 3306 } 3307 3308 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 3309 macp->m_driver = rsc; 3310 macp->m_dip = devinfo; 3311 macp->m_src_addr = ic->ic_macaddr; 3312 macp->m_callbacks = &rtw_m_callbacks; 3313 macp->m_min_sdu = 0; 3314 macp->m_max_sdu = IEEE80211_MTU; 3315 macp->m_pdata = &wd; 3316 macp->m_pdata_size = sizeof (wd); 3317 3318 err = mac_register(macp, &ic->ic_mach); 3319 mac_free(macp); 3320 if (err != 0) { 3321 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3322 "mac_register err %x\n", err); 3323 goto attach_fail8; 3324 } 3325 3326 /* Create minor node of type DDI_NT_NET_WIFI */ 3327 (void) snprintf(strbuf, sizeof (strbuf), "%s%d", 3328 "rtw", instance); 3329 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR, 3330 instance + 1, DDI_NT_NET_WIFI, 0); 3331 if (err != DDI_SUCCESS) { 3332 RTW_DPRINTF(RTW_DEBUG_ATTACH, "WARN: rtw: rtw_attach(): " 3333 "Create minor node failed - %d\n", err); 3334 goto attach_fail9; 3335 } 3336 mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 3337 rsc->sc_flags |= RTW_F_ATTACHED; 3338 rsc->sc_need_reschedule = 0; 3339 rsc->sc_invalid = 1; 3340 return (DDI_SUCCESS); 3341 attach_fail9: 3342 (void) mac_disable(ic->ic_mach); 3343 (void) mac_unregister(ic->ic_mach); 3344 attach_fail8: 3345 ddi_remove_intr(devinfo, 0, rsc->sc_iblock); 3346 attach_fail7: 3347 attach_fail6: 3348 rtw_mutex_destroy(rsc); 3349 attach_fail5: 3350 ieee80211_detach(ic); 3351 attach_fail4: 3352 rtw_rf_destroy(rsc->sc_rf); 3353 attach_fail3: 3354 rtw_srom_free(&rsc->sc_srom); 3355 attach_fail2: 3356 rtw_dma_free(rsc); 3357 attach_fail1: 3358 ddi_regs_map_free(&rsc->sc_regs.r_handle); 3359 attach_fail0: 3360 ddi_soft_state_free(rtw_soft_state_p, ddi_get_instance(devinfo)); 3361 return (DDI_FAILURE); 3362 } 3363 3364 static int32_t 3365 rtw_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 3366 { 3367 rtw_softc_t *rsc; 3368 3369 rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(devinfo)); 3370 ASSERT(rsc != NULL); 3371 3372 switch (cmd) { 3373 case DDI_DETACH: 3374 break; 3375 case DDI_SUSPEND: 3376 ieee80211_new_state(&rsc->sc_ic, IEEE80211_S_INIT, -1); 3377 mutex_enter(&rsc->sc_genlock); 3378 rsc->sc_flags |= RTW_F_SUSPEND; 3379 mutex_exit(&rsc->sc_genlock); 3380 if (rsc->sc_invalid == 0) { 3381 rtw_stop(rsc); 3382 mutex_enter(&rsc->sc_genlock); 3383 rsc->sc_flags |= RTW_F_PLUMBED; 3384 mutex_exit(&rsc->sc_genlock); 3385 } 3386 return (DDI_SUCCESS); 3387 default: 3388 return (DDI_FAILURE); 3389 } 3390 if (!(rsc->sc_flags & RTW_F_ATTACHED)) 3391 return (DDI_FAILURE); 3392 3393 if (mac_disable(rsc->sc_ic.ic_mach) != 0) 3394 return (DDI_FAILURE); 3395 3396 /* free intterrupt resources */ 3397 ddi_remove_intr(devinfo, 0, rsc->sc_iblock); 3398 3399 rtw_mutex_destroy(rsc); 3400 ieee80211_detach((ieee80211com_t *)rsc); 3401 /* 3402 * Unregister from the MAC layer subsystem 3403 */ 3404 (void) mac_unregister(rsc->sc_ic.ic_mach); 3405 3406 rtw_rf_destroy(rsc->sc_rf); 3407 rtw_srom_free(&rsc->sc_srom); 3408 rtw_dma_free(rsc); 3409 ddi_remove_minor_node(devinfo, NULL); 3410 ddi_regs_map_free(&rsc->sc_regs.r_handle); 3411 3412 ddi_soft_state_free(rtw_soft_state_p, ddi_get_instance(devinfo)); 3413 3414 return (DDI_SUCCESS); 3415 } 3416