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