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 if (sr->sr_content == NULL) { 820 cmn_err(CE_WARN, "%s: unable to allocate SROM buffer\n", 821 dvname); 822 return (ENOMEM); 823 } 824 825 (void) memset(sr->sr_content, 0, sr->sr_size); 826 827 /* 828 * RTL8180 has a single 8-bit register for controlling the 829 * 93cx6 SROM. There is no "ready" bit. The RTL8180 830 * input/output sense is the reverse of read_seeprom's. 831 */ 832 sd.sd_handle = regs->r_handle; 833 sd.sd_base = regs->r_base; 834 sd.sd_regsize = 1; 835 sd.sd_control_offset = RTW_9346CR; 836 sd.sd_status_offset = RTW_9346CR; 837 sd.sd_dataout_offset = RTW_9346CR; 838 sd.sd_CK = RTW_9346CR_EESK; 839 sd.sd_CS = RTW_9346CR_EECS; 840 sd.sd_DI = RTW_9346CR_EEDO; 841 sd.sd_DO = RTW_9346CR_EEDI; 842 /* 843 * make read_seeprom enter EEPROM read/write mode 844 */ 845 sd.sd_MS = ecr; 846 sd.sd_RDY = 0; 847 848 /* 849 * TBD bus barriers 850 */ 851 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 852 cmn_err(CE_WARN, "%s: could not read SROM\n", dvname); 853 kmem_free(sr->sr_content, sr->sr_size); 854 sr->sr_content = NULL; 855 return (-1); /* XXX */ 856 } 857 858 /* 859 * end EEPROM read/write mode 860 */ 861 RTW_WRITE8(regs, RTW_9346CR, 862 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 863 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 864 865 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 866 return (rc); 867 868 #ifdef SROM_DEBUG 869 { 870 int i; 871 RTW_DPRINTF(RTW_DEBUG_ATTACH, 872 "\n%s: serial ROM:\n\t", dvname); 873 for (i = 0; i < sr->sr_size/2; i++) { 874 RTW_DPRINTF(RTW_DEBUG_ATTACH, 875 "offset-0x%x: %04x", 2*i, sr->sr_content[i]); 876 } 877 } 878 #endif /* DEBUG */ 879 return (0); 880 } 881 882 static void 883 rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid, 884 const char *dvname) 885 { 886 uint8_t cfg4; 887 const char *method; 888 889 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 890 891 switch (rfchipid) { 892 default: 893 cfg4 |= LSHIFT(0, RTW_CONFIG4_RFTYPE_MASK); 894 method = "fallback"; 895 break; 896 case RTW_RFCHIPID_INTERSIL: 897 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 898 method = "Intersil"; 899 break; 900 case RTW_RFCHIPID_PHILIPS: 901 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 902 method = "Philips"; 903 break; 904 case RTW_RFCHIPID_GCT: /* XXX a guess */ 905 case RTW_RFCHIPID_RFMD: 906 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 907 method = "RFMD"; 908 break; 909 } 910 911 RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 912 913 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 914 915 RTW_DPRINTF(RTW_DEBUG_INIT, 916 "%s: %s RF programming method, %02x\n", dvname, method, 917 RTW_READ8(regs, RTW_CONFIG4)); 918 } 919 920 static void 921 rtw_init_channels(enum rtw_locale locale, 922 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], 923 const char *dvname) 924 { 925 int i; 926 const char *name = NULL; 927 #define ADD_CHANNEL(_chans, _chan) { \ 928 (*_chans)[_chan].ich_flags = IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK;\ 929 (*_chans)[_chan].ich_freq = \ 930 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ich_flags);\ 931 } 932 933 switch (locale) { 934 case RTW_LOCALE_USA: /* 1-11 */ 935 name = "USA"; 936 for (i = 1; i <= 11; i++) 937 ADD_CHANNEL(chans, i); 938 break; 939 case RTW_LOCALE_JAPAN: /* 1-14 */ 940 name = "Japan"; 941 ADD_CHANNEL(chans, 14); 942 for (i = 1; i <= 14; i++) 943 ADD_CHANNEL(chans, i); 944 break; 945 case RTW_LOCALE_EUROPE: /* 1-13 */ 946 name = "Europe"; 947 for (i = 1; i <= 13; i++) 948 ADD_CHANNEL(chans, i); 949 break; 950 default: /* 10-11 allowed by most countries */ 951 name = "<unknown>"; 952 for (i = 10; i <= 11; i++) 953 ADD_CHANNEL(chans, i); 954 break; 955 } 956 RTW_DPRINTF(RTW_DEBUG_ATTACH, "%s: Geographic Location %s\n", 957 dvname, name); 958 #undef ADD_CHANNEL 959 } 960 961 static void 962 rtw_set80211props(struct ieee80211com *ic) 963 { 964 ic->ic_phytype = IEEE80211_T_DS; 965 ic->ic_opmode = IEEE80211_M_STA; 966 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 967 IEEE80211_C_SHPREAMBLE; 968 /* IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP */ 969 970 ic->ic_sup_rates[IEEE80211_MODE_11B] = rtw_rateset_11b; 971 } 972 973 /*ARGSUSED*/ 974 static void 975 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale, 976 const char *dvname) 977 { 978 uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 979 980 switch (cfg0 & RTW_CONFIG0_GL_MASK) { 981 case RTW_CONFIG0_GL_USA: 982 *locale = RTW_LOCALE_USA; 983 break; 984 case RTW_CONFIG0_GL_JAPAN: 985 *locale = RTW_LOCALE_JAPAN; 986 break; 987 case RTW_CONFIG0_GL_EUROPE: 988 *locale = RTW_LOCALE_EUROPE; 989 break; 990 default: 991 *locale = RTW_LOCALE_UNKNOWN; 992 break; 993 } 994 } 995 996 static int 997 rtw_identify_sta(struct rtw_regs *regs, uint8_t *addr, 998 const char *dvname) 999 { 1000 uint32_t idr0 = RTW_READ(regs, RTW_IDR0), 1001 idr1 = RTW_READ(regs, RTW_IDR1); 1002 1003 *addr = MASK_AND_RSHIFT(idr0, BITS(0, 7)); 1004 *(addr + 1) = MASK_AND_RSHIFT(idr0, BITS(8, 15)); 1005 *(addr + 2) = MASK_AND_RSHIFT(idr0, BITS(16, 23)); 1006 *(addr + 3) = MASK_AND_RSHIFT(idr0, BITS(24, 31)); 1007 1008 *(addr + 4) = MASK_AND_RSHIFT(idr1, BITS(0, 7)); 1009 *(addr + 5) = MASK_AND_RSHIFT(idr1, BITS(8, 15)); 1010 1011 RTW_DPRINTF(RTW_DEBUG_ATTACH, 1012 "%s: 802.11mac address %x:%x:%x:%x:%x:%x\n", dvname, 1013 *addr, *(addr+1), *(addr+2), *(addr+3), *(addr+4), *(addr+5)); 1014 1015 return (0); 1016 } 1017 1018 static uint8_t 1019 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 1020 struct ieee80211_channel *chan) 1021 { 1022 uint32_t idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 1023 return (RTW_SR_GET(sr, idx)); 1024 } 1025 1026 static void 1027 rtw_rxdesc_init(rtw_softc_t *rsc, struct rtw_rxbuf *rbf, int idx, int is_last) 1028 { 1029 uint32_t ctl = 0; 1030 uint8_t *buf = (uint8_t *)rbf->bf_dma.mem_va; 1031 1032 ASSERT(rbf != NULL); 1033 rbf->rxdesc->rd_buf = (rbf->bf_dma.cookie.dmac_address); 1034 bzero(buf, rbf->bf_dma.alength); 1035 RTW_DMA_SYNC(rbf->bf_dma, DDI_DMA_SYNC_FORDEV); 1036 1037 ctl = (rbf->bf_dma.alength & 0xfff) | RTW_RXCTL_OWN; 1038 1039 if (is_last) 1040 ctl |= RTW_RXCTL_EOR; 1041 1042 rbf->rxdesc->rd_ctl = (ctl); 1043 /* sync the mbuf */ 1044 1045 /* sync the descriptor */ 1046 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 1047 RTW_DESC_OFFSET(hd_rx, idx), 1048 sizeof (struct rtw_rxdesc), 1049 DDI_DMA_SYNC_FORDEV); 1050 } 1051 1052 static void 1053 rtw_idle(struct rtw_regs *regs) 1054 { 1055 int active; 1056 1057 /* request stop DMA; wait for packets to stop transmitting. */ 1058 1059 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 1060 1061 for (active = 0; active < 300 && 1062 (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ALL) != 0; active++) 1063 drv_usecwait(10); 1064 } 1065 1066 static void 1067 rtw_io_enable(rtw_softc_t *rsc, uint8_t flags, int enable) 1068 { 1069 uint8_t cr; 1070 struct rtw_regs *regs = &rsc->sc_regs; 1071 1072 RTW_DPRINTF(RTW_DEBUG_IOSTATE, "%s: %s 0x%02x\n", __func__, 1073 enable ? "enable" : "disable", flags); 1074 1075 cr = RTW_READ8(regs, RTW_CR); 1076 1077 /* The receive engine will always start at RDSAR. */ 1078 if (enable && (flags & ~cr & RTW_CR_RE)) { 1079 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 1080 RTW_DESC_OFFSET(hd_rx, 0), 1081 sizeof (struct rtw_rxdesc), 1082 DDI_DMA_SYNC_FORCPU); 1083 rsc->rx_next = 0; 1084 rtw_rxdesc_init(rsc, rsc->rxbuf_h, 0, 0); 1085 } 1086 1087 if (enable) 1088 cr |= flags; 1089 else 1090 cr &= ~flags; 1091 RTW_WRITE8(regs, RTW_CR, cr); 1092 (void) RTW_READ8(regs, RTW_CR); 1093 } 1094 1095 /* 1096 * Allocate an area of memory and a DMA handle for accessing it 1097 */ 1098 static int 1099 rtw_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr, 1100 size_t memsize, ddi_device_acc_attr_t *attr_p, uint_t alloc_flags, 1101 uint_t bind_flags, dma_area_t *dma_p) 1102 { 1103 int err; 1104 1105 /* 1106 * Allocate handle 1107 */ 1108 err = ddi_dma_alloc_handle(devinfo, dma_attr, 1109 DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl); 1110 if (err != DDI_SUCCESS) 1111 return (DDI_FAILURE); 1112 1113 /* 1114 * Allocate memory 1115 */ 1116 err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p, 1117 alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va, 1118 &dma_p->alength, &dma_p->acc_hdl); 1119 if (err != DDI_SUCCESS) 1120 return (DDI_FAILURE); 1121 1122 /* 1123 * Bind the two together 1124 */ 1125 err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL, 1126 dma_p->mem_va, dma_p->alength, bind_flags, 1127 DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies); 1128 if ((dma_p->ncookies != 1) || (err != DDI_DMA_MAPPED)) 1129 return (DDI_FAILURE); 1130 1131 dma_p->nslots = ~0U; 1132 dma_p->size = ~0U; 1133 dma_p->token = ~0U; 1134 dma_p->offset = 0; 1135 return (DDI_SUCCESS); 1136 } 1137 1138 /* 1139 * Free one allocated area of DMAable memory 1140 */ 1141 static void 1142 rtw_free_dma_mem(dma_area_t *dma_p) 1143 { 1144 if (dma_p->dma_hdl != NULL) { 1145 (void) ddi_dma_unbind_handle(dma_p->dma_hdl); 1146 if (dma_p->acc_hdl != NULL) { 1147 ddi_dma_mem_free(&dma_p->acc_hdl); 1148 dma_p->acc_hdl = NULL; 1149 } 1150 ddi_dma_free_handle(&dma_p->dma_hdl); 1151 dma_p->ncookies = 0; 1152 dma_p->dma_hdl = NULL; 1153 } 1154 } 1155 1156 static void 1157 rtw_dma_free(rtw_softc_t *rsc) 1158 { 1159 struct rtw_txbuf *txbf; 1160 struct rtw_rxbuf *rxbf; 1161 int i, j; 1162 1163 /* Free TX DMA buffer */ 1164 for (i = 0; i < RTW_NTXPRI; i++) { 1165 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1166 while (txbf != NULL) { 1167 rtw_free_dma_mem(&txbf->bf_dma); 1168 list_remove(&rsc->sc_txq[i].tx_free_list, txbf); 1169 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1170 } 1171 list_destroy(&rsc->sc_txq[i].tx_free_list); 1172 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1173 while (txbf != NULL) { 1174 rtw_free_dma_mem(&txbf->bf_dma); 1175 list_remove(&rsc->sc_txq[i].tx_dirty_list, txbf); 1176 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1177 } 1178 list_destroy(&rsc->sc_txq[i].tx_dirty_list); 1179 1180 if (rsc->sc_txq[i].txbuf_h != NULL) { 1181 kmem_free(rsc->sc_txq[i].txbuf_h, 1182 sizeof (struct rtw_txbuf) * rtw_qlen[i]); 1183 rsc->sc_txq[i].txbuf_h = NULL; 1184 } 1185 } 1186 1187 /* Free RX DMA buffer */ 1188 rxbf = rsc->rxbuf_h; 1189 for (j = 0; j < RTW_RXQLEN; j++) { 1190 rtw_free_dma_mem(&rxbf->bf_dma); 1191 rxbf++; 1192 } 1193 1194 if (rsc->rxbuf_h != NULL) { 1195 kmem_free(rsc->rxbuf_h, 1196 sizeof (struct rtw_rxbuf) * RTW_RXQLEN); 1197 rsc->rxbuf_h = NULL; 1198 } 1199 1200 rtw_free_dma_mem(&rsc->sc_desc_dma); 1201 } 1202 1203 static int 1204 rtw_dma_init(dev_info_t *devinfo, rtw_softc_t *rsc) 1205 { 1206 int i, j, err; 1207 size_t size; 1208 uint32_t buflen; 1209 struct rtw_txdesc *txds; 1210 struct rtw_rxdesc *rxds; 1211 struct rtw_txbuf *txbf; 1212 struct rtw_rxbuf *rxbf; 1213 uint32_t phybaseaddr, ptx[RTW_NTXPRI], prx; 1214 caddr_t virbaseaddr, vtx[RTW_NTXPRI], vrx; 1215 1216 /* DMA buffer size for each TX/RX packet */ 1217 rsc->sc_dmabuf_size = roundup(sizeof (struct ieee80211_frame) + 0x100 + 1218 IEEE80211_MTU + IEEE80211_CRC_LEN + sizeof (struct ieee80211_llc) + 1219 (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + 1220 IEEE80211_WEP_CRCLEN), rsc->sc_cachelsz); 1221 size = sizeof (struct rtw_descs); 1222 err = rtw_alloc_dma_mem(devinfo, &dma_attr_desc, size, 1223 &rtw_desc_accattr, 1224 DDI_DMA_CONSISTENT, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1225 &rsc->sc_desc_dma); 1226 if (err != DDI_SUCCESS) 1227 goto error; 1228 phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address; 1229 virbaseaddr = rsc->sc_desc_dma.mem_va; 1230 ptx[0] = RTW_RING_BASE(phybaseaddr, hd_txlo); 1231 ptx[1] = RTW_RING_BASE(phybaseaddr, hd_txmd); 1232 ptx[2] = RTW_RING_BASE(phybaseaddr, hd_txhi); 1233 ptx[3] = RTW_RING_BASE(phybaseaddr, hd_bcn); 1234 vtx[0] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txlo)); 1235 vtx[1] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txmd)); 1236 vtx[2] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_txhi)); 1237 vtx[3] = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_bcn)); 1238 for (i = 0; i < RTW_NTXPRI; i++) { 1239 RTW_DPRINTF(RTW_DEBUG_DMA, "p[%d]=%x, v[%d]=%x", i, ptx[i], 1240 i, vtx[i]); 1241 RTW_DPRINTF(RTW_DEBUG_DMA, "ring%d:", i); 1242 list_create(&rsc->sc_txq[i].tx_free_list, 1243 sizeof (struct rtw_txbuf), 1244 offsetof(struct rtw_txbuf, bf_node)); 1245 list_create(&rsc->sc_txq[i].tx_dirty_list, 1246 sizeof (struct rtw_txbuf), 1247 offsetof(struct rtw_txbuf, bf_node)); 1248 /* virtual address of the first descriptor */ 1249 rsc->sc_txq[i].txdesc_h = 1250 (struct rtw_txdesc *)(uintptr_t)vtx[i]; 1251 1252 txds = rsc->sc_txq[i].txdesc_h; 1253 /* allocate data structures to describe TX DMA buffers */ 1254 buflen = sizeof (struct rtw_txbuf) * rtw_qlen[i]; 1255 txbf = (struct rtw_txbuf *)kmem_zalloc(buflen, KM_SLEEP); 1256 rsc->sc_txq[i].txbuf_h = txbf; 1257 for (j = 0; j < rtw_qlen[i]; j++, txbf++, txds++) { 1258 txbf->txdesc = txds; 1259 txbf->bf_daddr = ptx[i] + ((uintptr_t)txds - 1260 (uintptr_t)rsc->sc_txq[i].txdesc_h); 1261 list_insert_tail(&rsc->sc_txq[i].tx_free_list, txbf); 1262 1263 /* alloc DMA memory */ 1264 err = rtw_alloc_dma_mem(devinfo, &dma_attr_txbuf, 1265 rsc->sc_dmabuf_size, 1266 &rtw_buf_accattr, 1267 DDI_DMA_STREAMING, 1268 DDI_DMA_WRITE | DDI_DMA_STREAMING, 1269 &txbf->bf_dma); 1270 if (err != DDI_SUCCESS) 1271 goto error; 1272 RTW_DPRINTF(RTW_DEBUG_DMA, "pbufaddr[%d]=%x", 1273 j, txbf->bf_dma.cookie.dmac_address); 1274 } 1275 } 1276 prx = RTW_RING_BASE(phybaseaddr, hd_rx); 1277 vrx = (caddr_t)(RTW_RING_BASE(virbaseaddr, hd_rx)); 1278 /* virtual address of the first descriptor */ 1279 rsc->rxdesc_h = (struct rtw_rxdesc *)(uintptr_t)vrx; 1280 rxds = rsc->rxdesc_h; 1281 1282 /* allocate data structures to describe RX DMA buffers */ 1283 buflen = sizeof (struct rtw_rxbuf) * RTW_RXQLEN; 1284 rxbf = (struct rtw_rxbuf *)kmem_zalloc(buflen, KM_SLEEP); 1285 rsc->rxbuf_h = rxbf; 1286 1287 for (j = 0; j < RTW_RXQLEN; j++, rxbf++, rxds++) { 1288 rxbf->rxdesc = rxds; 1289 rxbf->bf_daddr = 1290 prx + ((uintptr_t)rxds - (uintptr_t)rsc->rxdesc_h); 1291 1292 /* alloc DMA memory */ 1293 err = rtw_alloc_dma_mem(devinfo, &dma_attr_rxbuf, 1294 rsc->sc_dmabuf_size, 1295 &rtw_buf_accattr, 1296 DDI_DMA_STREAMING, DDI_DMA_READ | DDI_DMA_STREAMING, 1297 &rxbf->bf_dma); 1298 if (err != DDI_SUCCESS) 1299 goto error; 1300 } 1301 1302 return (DDI_SUCCESS); 1303 error: 1304 return (DDI_FAILURE); 1305 } 1306 1307 static void 1308 rtw_hwring_setup(rtw_softc_t *rsc) 1309 { 1310 struct rtw_regs *regs = &rsc->sc_regs; 1311 uint32_t phybaseaddr; 1312 1313 phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address; 1314 1315 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(phybaseaddr, hd_rx)); 1316 RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(phybaseaddr, hd_txlo)); 1317 RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(phybaseaddr, hd_txmd)); 1318 RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(phybaseaddr, hd_txhi)); 1319 RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(phybaseaddr, hd_bcn)); 1320 rsc->hw_start = RTW_READ(regs, RTW_TNPDA); 1321 rsc->hw_go = RTW_READ(regs, RTW_TNPDA); 1322 } 1323 1324 static void 1325 rtw_swring_setup(rtw_softc_t *rsc, int flag) 1326 { 1327 int i, j; 1328 int is_last; 1329 struct rtw_txbuf *txbf; 1330 struct rtw_rxbuf *rxbf; 1331 uint32_t phybaseaddr, ptx[RTW_NTXPRI], baddr_desc, taddr_desc; 1332 1333 phybaseaddr = rsc->sc_desc_dma.cookie.dmac_address; 1334 ptx[0] = RTW_RING_BASE(phybaseaddr, hd_txlo); 1335 ptx[1] = RTW_RING_BASE(phybaseaddr, hd_txmd); 1336 ptx[2] = RTW_RING_BASE(phybaseaddr, hd_txhi); 1337 ptx[3] = RTW_RING_BASE(phybaseaddr, hd_bcn); 1338 RTW_DMA_SYNC(rsc->sc_desc_dma, DDI_DMA_SYNC_FORDEV); 1339 /* sync tx desc and tx buf */ 1340 for (i = 0; i < RTW_NTXPRI; i++) { 1341 rsc->sc_txq[i].tx_prod = rsc->sc_txq[i].tx_cons = 0; 1342 rsc->sc_txq[i].tx_nfree = rtw_qlen[i]; 1343 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1344 while (txbf != NULL) { 1345 list_remove(&rsc->sc_txq[i].tx_free_list, txbf); 1346 txbf = list_head(&rsc->sc_txq[i].tx_free_list); 1347 } 1348 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1349 while (txbf != NULL) { 1350 list_remove(&rsc->sc_txq[i].tx_dirty_list, txbf); 1351 txbf = list_head(&rsc->sc_txq[i].tx_dirty_list); 1352 } 1353 txbf = rsc->sc_txq[i].txbuf_h; 1354 baddr_desc = ptx[i]; 1355 taddr_desc = baddr_desc + sizeof (struct rtw_txdesc); 1356 for (j = 0; j < rtw_qlen[i]; j++) { 1357 list_insert_tail(&rsc->sc_txq[i].tx_free_list, txbf); 1358 if (j == (rtw_qlen[i] - 1)) { 1359 is_last = 1; 1360 } else { 1361 is_last = 0; 1362 } 1363 1364 if (is_last) { 1365 txbf->txdesc->td_next = baddr_desc; 1366 } else { 1367 txbf->txdesc->td_next = taddr_desc; 1368 } 1369 txbf->next_bf_daddr = txbf->txdesc->td_next; 1370 RTW_DMA_SYNC(txbf->bf_dma, DDI_DMA_SYNC_FORDEV); 1371 txbf->order = j; 1372 txbf++; 1373 taddr_desc += sizeof (struct rtw_txdesc); 1374 } 1375 } 1376 if (!flag) 1377 return; 1378 1379 /* sync rx desc and rx buf */ 1380 rsc->rx_next = 0; 1381 rxbf = rsc->rxbuf_h; 1382 for (j = 0; j < RTW_RXQLEN; j++) { 1383 RTW_DMA_SYNC(rxbf->bf_dma, DDI_DMA_SYNC_FORCPU); 1384 if (j == (RTW_RXQLEN - 1)) 1385 is_last = 1; 1386 else 1387 is_last = 0; 1388 rtw_rxdesc_init(rsc, rxbf, j, is_last); 1389 rxbf++; 1390 } 1391 } 1392 1393 static void 1394 rtw_resume_ticks(rtw_softc_t *rsc) 1395 { 1396 RTW_WRITE(&rsc->sc_regs, RTW_TINT, 0xffffffff); 1397 } 1398 1399 const char * 1400 rtw_pwrstate_string(enum rtw_pwrstate power) 1401 { 1402 switch (power) { 1403 case RTW_ON: 1404 return ("on"); 1405 case RTW_SLEEP: 1406 return ("sleep"); 1407 case RTW_OFF: 1408 return ("off"); 1409 default: 1410 return ("unknown"); 1411 } 1412 } 1413 1414 /* 1415 * XXX For Maxim, I am using the RFMD settings gleaned from the 1416 * reference driver, plus a magic Maxim "ON" value that comes from 1417 * the Realtek document "Windows PG for Rtl8180." 1418 */ 1419 /*ARGSUSED*/ 1420 static void 1421 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1422 int before_rf, int digphy) 1423 { 1424 uint32_t anaparm; 1425 1426 anaparm = RTW_READ(regs, RTW_ANAPARM); 1427 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1428 1429 switch (power) { 1430 case RTW_OFF: 1431 if (before_rf) 1432 return; 1433 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 1434 anaparm |= RTW_ANAPARM_TXDACOFF; 1435 break; 1436 case RTW_SLEEP: 1437 if (!before_rf) 1438 return; 1439 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 1440 anaparm |= RTW_ANAPARM_TXDACOFF; 1441 break; 1442 case RTW_ON: 1443 if (!before_rf) 1444 return; 1445 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 1446 break; 1447 } 1448 RTW_DPRINTF(RTW_DEBUG_PWR, 1449 "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1450 __func__, rtw_pwrstate_string(power), 1451 (before_rf) ? "before" : "after", anaparm); 1452 1453 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1454 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1455 } 1456 1457 /* 1458 * XXX I am using the RFMD settings gleaned from the reference 1459 * driver. They agree 1460 */ 1461 /*ARGSUSED*/ 1462 static void 1463 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1464 int before_rf, int digphy) 1465 { 1466 uint32_t anaparm; 1467 1468 anaparm = RTW_READ(regs, RTW_ANAPARM); 1469 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1470 1471 switch (power) { 1472 case RTW_OFF: 1473 if (before_rf) 1474 return; 1475 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 1476 anaparm |= RTW_ANAPARM_TXDACOFF; 1477 break; 1478 case RTW_SLEEP: 1479 if (!before_rf) 1480 return; 1481 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 1482 anaparm |= RTW_ANAPARM_TXDACOFF; 1483 break; 1484 case RTW_ON: 1485 if (!before_rf) 1486 return; 1487 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 1488 break; 1489 } 1490 RTW_DPRINTF(RTW_DEBUG_PWR, 1491 "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1492 __func__, rtw_pwrstate_string(power), 1493 (before_rf) ? "before" : "after", anaparm); 1494 1495 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1496 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1497 } 1498 1499 static void 1500 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1501 int before_rf, int digphy) 1502 { 1503 uint32_t anaparm; 1504 1505 anaparm = RTW_READ(regs, RTW_ANAPARM); 1506 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1507 1508 switch (power) { 1509 case RTW_OFF: 1510 if (before_rf) 1511 return; 1512 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 1513 anaparm |= RTW_ANAPARM_TXDACOFF; 1514 break; 1515 case RTW_SLEEP: 1516 if (!before_rf) 1517 return; 1518 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 1519 anaparm |= RTW_ANAPARM_TXDACOFF; 1520 break; 1521 case RTW_ON: 1522 if (!before_rf) 1523 return; 1524 if (digphy) { 1525 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 1526 /* XXX guess */ 1527 anaparm |= RTW_ANAPARM_TXDACOFF; 1528 } else 1529 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 1530 break; 1531 } 1532 RTW_DPRINTF(RTW_DEBUG_PWR, 1533 "%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 1534 __func__, rtw_pwrstate_string(power), 1535 (before_rf) ? "before" : "after", anaparm); 1536 1537 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 1538 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 1539 } 1540 1541 static void 1542 rtw_pwrstate0(rtw_softc_t *rsc, enum rtw_pwrstate power, int before_rf, 1543 int digphy) 1544 { 1545 struct rtw_regs *regs = &rsc->sc_regs; 1546 1547 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 1548 1549 (*rsc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 1550 1551 rtw_set_access(regs, RTW_ACCESS_NONE); 1552 } 1553 1554 static void 1555 rtw_rf_destroy(struct rtw_rf *rf) 1556 { 1557 (*rf->rf_destroy)(rf); 1558 } 1559 1560 static int 1561 rtw_rf_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 1562 { 1563 return (*rf->rf_pwrstate)(rf, power); 1564 } 1565 1566 static int 1567 rtw_pwrstate(rtw_softc_t *rsc, enum rtw_pwrstate power) 1568 { 1569 int rc; 1570 1571 RTW_DPRINTF(RTW_DEBUG_PWR, 1572 "%s: %s->%s\n", __func__, 1573 rtw_pwrstate_string(rsc->sc_pwrstate), rtw_pwrstate_string(power)); 1574 1575 if (rsc->sc_pwrstate == power) 1576 return (0); 1577 1578 rtw_pwrstate0(rsc, power, 1, rsc->sc_flags & RTW_F_DIGPHY); 1579 rc = rtw_rf_pwrstate(rsc->sc_rf, power); 1580 rtw_pwrstate0(rsc, power, 0, rsc->sc_flags & RTW_F_DIGPHY); 1581 1582 switch (power) { 1583 case RTW_ON: 1584 /* TBD set LEDs */ 1585 break; 1586 case RTW_SLEEP: 1587 /* TBD */ 1588 break; 1589 case RTW_OFF: 1590 /* TBD */ 1591 break; 1592 } 1593 if (rc == 0) 1594 rsc->sc_pwrstate = power; 1595 else 1596 rsc->sc_pwrstate = RTW_OFF; 1597 return (rc); 1598 } 1599 1600 void 1601 rtw_disable(rtw_softc_t *rsc) 1602 { 1603 int rc; 1604 1605 if ((rsc->sc_flags & RTW_F_ENABLED) == 0) 1606 return; 1607 1608 /* turn off PHY */ 1609 if ((rsc->sc_flags & RTW_F_INVALID) == 0 && 1610 (rc = rtw_pwrstate(rsc, RTW_OFF)) != 0) { 1611 cmn_err(CE_WARN, "failed to turn off PHY (%d)\n", rc); 1612 } 1613 1614 if (rsc->sc_disable != NULL) 1615 (*rsc->sc_disable)(rsc); 1616 1617 rsc->sc_flags &= ~RTW_F_ENABLED; 1618 } 1619 1620 int 1621 rtw_enable(rtw_softc_t *rsc) 1622 { 1623 if ((rsc->sc_flags & RTW_F_ENABLED) == 0) { 1624 if (rsc->sc_enable != NULL && (*rsc->sc_enable)(rsc) != 0) { 1625 cmn_err(CE_WARN, "device enable failed\n"); 1626 return (EIO); 1627 } 1628 rsc->sc_flags |= RTW_F_ENABLED; 1629 if (rtw_pwrstate(rsc, RTW_ON) != 0) 1630 cmn_err(CE_WARN, "PHY turn on failed\n"); 1631 } 1632 return (0); 1633 } 1634 1635 static void 1636 rtw_set_nettype(rtw_softc_t *rsc, enum ieee80211_opmode opmode) 1637 { 1638 uint8_t msr; 1639 1640 /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 1641 rtw_set_access(&rsc->sc_regs, RTW_ACCESS_CONFIG); 1642 1643 msr = RTW_READ8(&rsc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 1644 1645 switch (opmode) { 1646 case IEEE80211_M_AHDEMO: 1647 case IEEE80211_M_IBSS: 1648 msr |= RTW_MSR_NETYPE_ADHOC_OK; 1649 break; 1650 case IEEE80211_M_HOSTAP: 1651 msr |= RTW_MSR_NETYPE_AP_OK; 1652 break; 1653 case IEEE80211_M_STA: 1654 msr |= RTW_MSR_NETYPE_INFRA_OK; 1655 break; 1656 } 1657 RTW_WRITE8(&rsc->sc_regs, RTW_MSR, msr); 1658 1659 rtw_set_access(&rsc->sc_regs, RTW_ACCESS_NONE); 1660 } 1661 1662 static void 1663 rtw_pktfilt_load(rtw_softc_t *rsc) 1664 { 1665 struct rtw_regs *regs = &rsc->sc_regs; 1666 struct ieee80211com *ic = &rsc->sc_ic; 1667 1668 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 1669 rsc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK; 1670 rsc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK); 1671 1672 rsc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT; 1673 /* MAC auto-reset PHY (huh?) */ 1674 rsc->sc_rcr |= RTW_RCR_ENMARP; 1675 /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */ 1676 rsc->sc_rcr |= RTW_RCR_RXFTH_WHOLE |RTW_RCR_MXDMA_1024; 1677 1678 switch (ic->ic_opmode) { 1679 case IEEE80211_M_AHDEMO: 1680 case IEEE80211_M_IBSS: 1681 /* receive broadcasts in our BSS */ 1682 rsc->sc_rcr |= RTW_RCR_ADD3; 1683 break; 1684 default: 1685 break; 1686 } 1687 #if 0 1688 /* XXX accept all broadcast if scanning */ 1689 rsc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 1690 #endif 1691 RTW_WRITE(regs, RTW_MAR0, 0xffffffff); 1692 RTW_WRITE(regs, RTW_MAR1, 0xffffffff); 1693 rsc->sc_rcr |= RTW_RCR_AM; 1694 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 1695 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 1696 1697 RTW_DPRINTF(RTW_DEBUG_PKTFILT, 1698 "RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 1699 RTW_READ(regs, RTW_MAR0), 1700 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)); 1701 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 1702 } 1703 1704 static void 1705 rtw_transmit_config(struct rtw_regs *regs) 1706 { 1707 uint32_t tcr; 1708 1709 tcr = RTW_READ(regs, RTW_TCR); 1710 1711 tcr |= RTW_TCR_CWMIN; 1712 tcr &= ~RTW_TCR_MXDMA_MASK; 1713 tcr |= RTW_TCR_MXDMA_1024; 1714 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 1715 tcr &= ~RTW_TCR_LBK_MASK; 1716 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 1717 1718 /* set short/long retry limits */ 1719 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 1720 tcr |= LSHIFT(0x4, RTW_TCR_SRL_MASK) | LSHIFT(0x4, RTW_TCR_LRL_MASK); 1721 1722 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 1723 RTW_WRITE(regs, RTW_TCR, tcr); 1724 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 1725 } 1726 1727 int 1728 rtw_refine_setting(rtw_softc_t *rsc) 1729 { 1730 struct rtw_regs *regs; 1731 int rc = 0; 1732 1733 regs = &rsc->sc_regs; 1734 rc = rtw_reset(rsc); 1735 if (rc != 0) 1736 return (-1); 1737 1738 rtw_beacon_tx_disable(regs); 1739 rtw_io_enable(rsc, RTW_CR_RE|RTW_CR_TE, 1); 1740 rtw_set_mode(regs, RTW_EPROM_CMD_CONFIG); 1741 1742 rtw_transmit_config(regs); 1743 rtw_pktfilt_load(rsc); 1744 rtw_set_access(regs, RTW_ACCESS_CONFIG); 1745 RTW_WRITE(regs, RTW_TINT, 0xffffffff); 1746 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 1747 RTW_WRITE16(regs, RTW_BRSR, 0); 1748 1749 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 1750 rtw_set_access(regs, RTW_ACCESS_NONE); 1751 RTW_WRITE(regs, RTW_FEMR, 0xffff); 1752 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 1753 rtw_set_rfprog(regs, rsc->sc_rfchipid, "rtw"); 1754 1755 RTW_WRITE8(regs, RTW_PHYDELAY, rsc->sc_phydelay); 1756 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 1757 rtw_set_mode(regs, RTW_EPROM_CMD_NORMAL); 1758 return (0); 1759 } 1760 1761 static int 1762 rtw_tune(rtw_softc_t *rsc) 1763 { 1764 struct ieee80211com *ic = &rsc->sc_ic; 1765 uint32_t chan; 1766 int rc; 1767 int antdiv = rsc->sc_flags & RTW_F_ANTDIV, 1768 dflantb = rsc->sc_flags & RTW_F_DFLANTB; 1769 1770 ASSERT(ic->ic_curchan != NULL); 1771 1772 chan = ieee80211_chan2ieee(ic, ic->ic_curchan); 1773 RTW_DPRINTF(RTW_DEBUG_TUNE, "rtw: chan no = %x", chan); 1774 1775 if (chan == IEEE80211_CHAN_ANY) { 1776 cmn_err(CE_WARN, "%s: chan == IEEE80211_CHAN_ANY\n", __func__); 1777 return (-1); 1778 } 1779 1780 if (chan == rsc->sc_cur_chan) { 1781 RTW_DPRINTF(RTW_DEBUG_TUNE, 1782 "%s: already tuned chan %d\n", __func__, chan); 1783 return (0); 1784 } 1785 rtw_idle(&rsc->sc_regs); 1786 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 1787 ASSERT((rsc->sc_flags & RTW_F_ENABLED) != 0); 1788 1789 if ((rc = rtw_phy_init(&rsc->sc_regs, rsc->sc_rf, 1790 rtw_chan2txpower(&rsc->sc_srom, ic, ic->ic_curchan), 1791 rsc->sc_csthr, ic->ic_curchan->ich_freq, antdiv, 1792 dflantb, RTW_ON)) != 0) { 1793 /* XXX condition on powersaving */ 1794 cmn_err(CE_NOTE, "phy init failed\n"); 1795 } 1796 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 1); 1797 rtw_resume_ticks(rsc); 1798 rsc->sc_cur_chan = chan; 1799 return (rc); 1800 } 1801 1802 static int 1803 rtw_init(rtw_softc_t *rsc) 1804 { 1805 struct ieee80211com *ic = &rsc->sc_ic; 1806 int rc = 0; 1807 1808 rtw_stop(rsc); 1809 mutex_enter(&rsc->sc_genlock); 1810 if ((rc = rtw_enable(rsc)) != 0) 1811 goto out; 1812 rc = rtw_refine_setting(rsc); 1813 if (rc != 0) { 1814 mutex_exit(&rsc->sc_genlock); 1815 return (rc); 1816 } 1817 rtw_swring_setup(rsc, 1); 1818 rtw_hwring_setup(rsc); 1819 RTW_WRITE16(&rsc->sc_regs, RTW_BSSID16, 0x0); 1820 RTW_WRITE(&rsc->sc_regs, RTW_BSSID32, 0x0); 1821 rtw_enable_interrupts(rsc); 1822 1823 ic->ic_ibss_chan = &ic->ic_sup_channels[1]; 1824 ic->ic_curchan = ic->ic_ibss_chan; 1825 RTW_DPRINTF(RTW_DEBUG_TUNE, "%s: channel %d freq %d flags 0x%04x\n", 1826 __func__, ieee80211_chan2ieee(ic, ic->ic_curchan), 1827 ic->ic_curchan->ich_freq, ic->ic_curchan->ich_flags); 1828 rsc->sc_invalid = 0; 1829 out: 1830 mutex_exit(&rsc->sc_genlock); 1831 return (rc); 1832 } 1833 1834 static struct rtw_rf * 1835 rtw_rf_attach(rtw_softc_t *rsc, enum rtw_rfchipid rfchipid, int digphy) 1836 { 1837 rtw_rf_write_t rf_write; 1838 struct rtw_rf *rf; 1839 int rtw_host_rfio; 1840 1841 switch (rfchipid) { 1842 default: 1843 rf_write = rtw_rf_hostwrite; 1844 break; 1845 case RTW_RFCHIPID_INTERSIL: 1846 case RTW_RFCHIPID_PHILIPS: 1847 case RTW_RFCHIPID_GCT: /* XXX a guess */ 1848 case RTW_RFCHIPID_RFMD: 1849 rtw_host_rfio = 1; 1850 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite; 1851 break; 1852 } 1853 1854 switch (rfchipid) { 1855 case RTW_RFCHIPID_MAXIM: 1856 rf = rtw_max2820_create(&rsc->sc_regs, rf_write, 0); 1857 rsc->sc_pwrstate_cb = rtw_maxim_pwrstate; 1858 break; 1859 case RTW_RFCHIPID_PHILIPS: 1860 rf = rtw_sa2400_create(&rsc->sc_regs, rf_write, digphy); 1861 rsc->sc_pwrstate_cb = rtw_philips_pwrstate; 1862 break; 1863 case RTW_RFCHIPID_RFMD: 1864 /* XXX RFMD has no RF constructor */ 1865 rsc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 1866 /*FALLTHROUGH*/ 1867 default: 1868 return (NULL); 1869 } 1870 if (rf != NULL) { 1871 rf->rf_continuous_tx_cb = 1872 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 1873 rf->rf_continuous_tx_arg = (void *)rsc; 1874 } 1875 return (rf); 1876 } 1877 1878 /* 1879 * Revision C and later use a different PHY delay setting than 1880 * revisions A and B. 1881 */ 1882 static uint8_t 1883 rtw_check_phydelay(struct rtw_regs *regs, uint32_t rcr0) 1884 { 1885 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 1886 #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 1887 1888 uint8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY); 1889 1890 RTW_WRITE(regs, RTW_RCR, REVAB); 1891 RTW_WBW(regs, RTW_RCR, RTW_RCR); 1892 RTW_WRITE(regs, RTW_RCR, REVC); 1893 1894 RTW_WBR(regs, RTW_RCR, RTW_RCR); 1895 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 1896 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 1897 1898 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */ 1899 RTW_SYNC(regs, RTW_RCR, RTW_RCR); 1900 1901 return (phydelay); 1902 #undef REVC 1903 } 1904 1905 static void rtw_intr_rx(rtw_softc_t *rsc); 1906 static void rtw_ring_recycling(rtw_softc_t *rsc, uint16_t isr, uint32_t pri); 1907 1908 static int 1909 rtw_get_rate(struct ieee80211com *ic) 1910 { 1911 uint8_t (*rates)[IEEE80211_RATE_MAXSIZE]; 1912 int rate; 1913 1914 rates = &ic->ic_bss->in_rates.ir_rates; 1915 1916 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) 1917 rate = ic->ic_fixed_rate; 1918 else if (ic->ic_state == IEEE80211_S_RUN) 1919 rate = (*rates)[ic->ic_bss->in_txrate]; 1920 else 1921 rate = 0; 1922 return (rate & IEEE80211_RATE_VAL); 1923 } 1924 1925 /* 1926 * Arguments in: 1927 * 1928 * paylen: payload length (no FCS, no WEP header) 1929 * 1930 * hdrlen: header length 1931 * 1932 * rate: MSDU speed, units 500kb/s 1933 * 1934 * flags: IEEE80211_F_SHPREAMBLE (use short preamble), 1935 * IEEE80211_F_SHSLOT (use short slot length) 1936 * 1937 * Arguments out: 1938 * 1939 * d: 802.11 Duration field for RTS, 1940 * 802.11 Duration field for data frame, 1941 * PLCP Length for data frame, 1942 * residual octets at end of data slot 1943 */ 1944 static int 1945 rtw_compute_duration1(int len, int use_ack, uint32_t flags, int rate, 1946 struct rtw_ieee80211_duration *d) 1947 { 1948 int pre, ctsrate; 1949 uint16_t ack, bitlen, data_dur, remainder; 1950 1951 /* 1952 * RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK 1953 * DATA reserves medium for SIFS | ACK 1954 * 1955 * XXXMYC: no ACK on multicast/broadcast or control packets 1956 */ 1957 1958 bitlen = len * 8; 1959 1960 pre = IEEE80211_DUR_DS_SIFS; 1961 if ((flags & IEEE80211_F_SHPREAMBLE) != 0) 1962 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE + 1963 IEEE80211_DUR_DS_FAST_PLCPHDR; 1964 else 1965 pre += IEEE80211_DUR_DS_LONG_PREAMBLE + 1966 IEEE80211_DUR_DS_SLOW_PLCPHDR; 1967 1968 d->d_residue = 0; 1969 data_dur = (bitlen * 2) / rate; 1970 remainder = (bitlen * 2) % rate; 1971 if (remainder != 0) { 1972 if (rate == 22) 1973 d->d_residue = (rate - remainder) / 16; 1974 data_dur++; 1975 } 1976 1977 switch (rate) { 1978 case 2: /* 1 Mb/s */ 1979 case 4: /* 2 Mb/s */ 1980 /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */ 1981 ctsrate = 2; 1982 break; 1983 case 11: /* 5.5 Mb/s */ 1984 case 22: /* 11 Mb/s */ 1985 case 44: /* 22 Mb/s */ 1986 /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */ 1987 ctsrate = 4; 1988 break; 1989 default: 1990 /* TBD */ 1991 return (-1); 1992 } 1993 1994 d->d_plcp_len = data_dur; 1995 1996 ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0; 1997 1998 d->d_rts_dur = 1999 pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate + 2000 pre + data_dur + 2001 ack; 2002 2003 d->d_data_dur = ack; 2004 2005 return (0); 2006 } 2007 2008 /* 2009 * Arguments in: 2010 * 2011 * wh: 802.11 header 2012 * 2013 * paylen: payload length (no FCS, no WEP header) 2014 * 2015 * rate: MSDU speed, units 500kb/s 2016 * 2017 * fraglen: fragment length, set to maximum (or higher) for no 2018 * fragmentation 2019 * 2020 * flags: IEEE80211_F_PRIVACY (hardware adds WEP), 2021 * IEEE80211_F_SHPREAMBLE (use short preamble), 2022 * IEEE80211_F_SHSLOT (use short slot length) 2023 * 2024 * Arguments out: 2025 * 2026 * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields 2027 * of first/only fragment 2028 * 2029 * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields 2030 * of first/only fragment 2031 */ 2032 static int 2033 rtw_compute_duration(struct ieee80211_frame *wh, int len, 2034 uint32_t flags, int fraglen, int rate, struct rtw_ieee80211_duration *d0, 2035 struct rtw_ieee80211_duration *dn, int *npktp) 2036 { 2037 int ack, rc; 2038 int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen; 2039 2040 /* don't think about addr4 here */ 2041 hdrlen = sizeof (struct ieee80211_frame); 2042 2043 paylen = len - hdrlen; 2044 2045 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) { 2046 overlen = 8 + IEEE80211_CRC_LEN; 2047 paylen -= 8; 2048 } else 2049 overlen = IEEE80211_CRC_LEN; 2050 2051 npkt = paylen / fraglen; 2052 lastlen0 = paylen % fraglen; 2053 2054 if (npkt == 0) /* no fragments */ 2055 lastlen = paylen + overlen; 2056 else if (lastlen0 != 0) { /* a short "tail" fragment */ 2057 lastlen = lastlen0 + overlen; 2058 npkt++; 2059 } else /* full-length "tail" fragment */ 2060 lastlen = fraglen + overlen; 2061 2062 if (npktp != NULL) 2063 *npktp = npkt; 2064 2065 if (npkt > 1) 2066 firstlen = fraglen + overlen; 2067 else 2068 firstlen = paylen + overlen; 2069 2070 ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) && 2071 (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != 2072 IEEE80211_FC0_TYPE_CTL; 2073 2074 rc = rtw_compute_duration1(firstlen + hdrlen, 2075 ack, flags, rate, d0); 2076 if (rc == -1) 2077 return (rc); 2078 2079 if (npkt <= 1) { 2080 *dn = *d0; 2081 return (0); 2082 } 2083 return (rtw_compute_duration1(lastlen + hdrlen, ack, flags, 2084 rate, dn)); 2085 } 2086 2087 static int 2088 rtw_assembly_80211(rtw_softc_t *rsc, struct rtw_txbuf *bf, 2089 mblk_t *mp) 2090 { 2091 ieee80211com_t *ic; 2092 struct rtw_txdesc *ds; 2093 struct ieee80211_frame *wh; 2094 uint8_t *buf; 2095 uint32_t ctl0 = 0, ctl1 = 0; 2096 int npkt, rate; 2097 struct rtw_ieee80211_duration d0, dn; 2098 int32_t iswep, pktlen, mblen; 2099 mblk_t *mp0; 2100 2101 ic = &rsc->sc_ic; 2102 ds = bf->txdesc; 2103 buf = (uint8_t *)bf->bf_dma.mem_va; 2104 bzero(buf, bf->bf_dma.alength); 2105 bzero((uint8_t *)ds, sizeof (struct rtw_txdesc)); 2106 wh = (struct ieee80211_frame *)mp->b_rptr; 2107 iswep = wh->i_fc[1] & IEEE80211_FC1_WEP; 2108 2109 /* ieee80211_crypto_encap() needs a single mblk */ 2110 mp0 = allocb(bf->bf_dma.alength, BPRI_MED); 2111 if (mp0 == NULL) { 2112 cmn_err(CE_WARN, "%s: allocb(mp) error", __func__); 2113 return (-1); 2114 } 2115 for (; mp != NULL; mp = mp->b_cont) { 2116 mblen = (uintptr_t)mp->b_wptr - (uintptr_t)mp->b_rptr; 2117 bcopy(mp->b_rptr, mp0->b_wptr, mblen); 2118 mp0->b_wptr += mblen; 2119 } 2120 2121 if (iswep) { 2122 struct ieee80211_key *k; 2123 2124 k = ieee80211_crypto_encap(ic, mp0); 2125 if (k == NULL) { 2126 cmn_err(CE_WARN, "%s: ieee80211_crypto_encap() error", 2127 __func__); 2128 freemsg(mp0); 2129 return (-1); 2130 } 2131 } 2132 pktlen = msgdsize(mp0); 2133 2134 #if 0 2135 RTW_DPRINTF(RTW_DEBUG_XMIT, "-----------send------begin--------"); 2136 ieee80211_dump_pkt((uint8_t *)(mp0->b_rptr), pktlen, 0, 0); 2137 RTW_DPRINTF(RTW_DEBUG_XMIT, "-----------send------end--------"); 2138 #endif 2139 /* RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV); */ 2140 if (pktlen > bf->bf_dma.alength) { 2141 cmn_err(CE_WARN, "%s: overlength packet pktlen = %d\n", 2142 __func__, pktlen); 2143 freemsg(mp0); 2144 return (-1); 2145 } 2146 bcopy(mp0->b_rptr, buf, pktlen); 2147 RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV); 2148 2149 /* setup descriptor */ 2150 ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 2151 2152 if (((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) && 2153 (ic->ic_bss->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 2154 ctl0 |= RTW_TXCTL0_SPLCP; 2155 } 2156 /* XXX do real rate control */ 2157 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2158 IEEE80211_FC0_TYPE_MGT) 2159 rate = 2; 2160 else { 2161 rate = MAX(2, rtw_get_rate(ic)); 2162 } 2163 ctl0 = ctl0 | 2164 LSHIFT(pktlen, RTW_TXCTL0_TPKTSIZE_MASK); 2165 2166 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: rate = %d", __func__, rate); 2167 2168 switch (rate) { 2169 default: 2170 case 2: 2171 ctl0 |= RTW_TXCTL0_RATE_1MBPS; 2172 break; 2173 case 4: 2174 ctl0 |= RTW_TXCTL0_RATE_2MBPS; 2175 break; 2176 case 11: 2177 ctl0 |= RTW_TXCTL0_RATE_5MBPS; 2178 break; 2179 case 22: 2180 ctl0 |= RTW_TXCTL0_RATE_11MBPS; 2181 break; 2182 } 2183 2184 /* XXX >= ? Compare after fragmentation? */ 2185 if (pktlen > ic->ic_rtsthreshold) { 2186 ctl0 |= RTW_TXCTL0_RTSEN; 2187 cmn_err(CE_NOTE, "%s: fragmentation: pktlen = %d", 2188 __func__, pktlen); 2189 } 2190 2191 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2192 IEEE80211_FC0_TYPE_MGT) { 2193 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN); 2194 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == 2195 IEEE80211_FC0_SUBTYPE_BEACON) 2196 ctl0 |= RTW_TXCTL0_BEACON; 2197 } 2198 2199 if (rtw_compute_duration(wh, pktlen, 2200 ic->ic_flags, ic->ic_fragthreshold, 2201 rate, &d0, &dn, &npkt) == -1) { 2202 RTW_DPRINTF(RTW_DEBUG_XMIT, 2203 "%s: fail compute duration\n", __func__); 2204 freemsg(mp0); 2205 return (-1); 2206 } 2207 *(uint16_t *)(uintptr_t)wh->i_dur = (d0.d_data_dur); 2208 2209 ctl1 = LSHIFT(d0.d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 2210 LSHIFT(d0.d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 2211 2212 if (d0.d_residue) 2213 ctl1 |= RTW_TXCTL1_LENGEXT; 2214 2215 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: duration=%x, ctl1=%x", __func__, 2216 *(uint16_t *)(uintptr_t)wh->i_dur, ctl1); 2217 2218 if (bf->bf_dma.alength > RTW_TXLEN_LENGTH_MASK) { 2219 RTW_DPRINTF(RTW_DEBUG_XMIT, 2220 "%s: seg too long\n", __func__); 2221 freemsg(mp0); 2222 return (-1); 2223 } 2224 ds->td_ctl0 = ctl0; 2225 ds->td_ctl0 |= RTW_TXCTL0_OWN | RTW_TXCTL0_LS | RTW_TXCTL0_FS; 2226 ds->td_ctl1 = ctl1; 2227 ds->td_buf = bf->bf_dma.cookie.dmac_address; 2228 ds->td_len = pktlen & 0xfff; 2229 ds->td_next = bf->next_bf_daddr; 2230 2231 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2232 RTW_DESC_OFFSET(hd_txmd, bf->order), 2233 sizeof (struct rtw_txdesc), 2234 DDI_DMA_SYNC_FORDEV); 2235 2236 RTW_DPRINTF(RTW_DEBUG_XMIT, 2237 "descriptor: order = %d, phy_addr=%x, ctl0=%x," 2238 " ctl1=%x, buf=%x, len=%x, next=%x", bf->order, 2239 bf->bf_daddr, ds->td_ctl0, ds->td_ctl1, 2240 ds->td_buf, ds->td_len, ds->td_next); 2241 rsc->sc_pktxmt64++; 2242 rsc->sc_bytexmt64 += pktlen; 2243 2244 freemsg(mp0); 2245 return (0); 2246 } 2247 2248 static int 2249 rtw_send(ieee80211com_t *ic, mblk_t *mp, uint8_t type) 2250 { 2251 rtw_softc_t *rsc = (rtw_softc_t *)ic; 2252 struct ieee80211_node *in = ic->ic_bss; 2253 struct rtw_txbuf *bf = NULL; 2254 int ret, i = RTW_TXPRIMD; 2255 2256 mutex_enter(&rsc->sc_txlock); 2257 mutex_enter(&rsc->sc_txq[i].txbuf_lock); 2258 bf = list_head(&rsc->sc_txq[i].tx_free_list); 2259 2260 if ((bf == NULL) || (rsc->sc_txq[i].tx_nfree <= 4)) { 2261 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: no tx buf\n", __func__); 2262 rsc->sc_noxmtbuf++; 2263 if ((type & IEEE80211_FC0_TYPE_MASK) == 2264 IEEE80211_FC0_TYPE_DATA) { 2265 RTW_DPRINTF(RTW_DEBUG_XMIT, "%s: need reschedule\n", 2266 __func__); 2267 rsc->sc_need_reschedule = 1; 2268 } else { 2269 freemsg(mp); 2270 } 2271 mutex_exit(&rsc->sc_txq[i].txbuf_lock); 2272 mutex_exit(&rsc->sc_txlock); 2273 return (1); 2274 } 2275 list_remove(&rsc->sc_txq[i].tx_free_list, bf); 2276 rsc->sc_txq[i].tx_nfree--; 2277 2278 /* assemble 802.11 frame here */ 2279 ret = rtw_assembly_80211(rsc, bf, mp); 2280 if (ret != 0) { 2281 cmn_err(CE_WARN, "%s assembly frame error\n", __func__); 2282 mutex_exit(&rsc->sc_txq[i].txbuf_lock); 2283 mutex_exit(&rsc->sc_txlock); 2284 if ((type & IEEE80211_FC0_TYPE_MASK) != 2285 IEEE80211_FC0_TYPE_DATA) { 2286 freemsg(mp); 2287 } 2288 return (1); 2289 } 2290 list_insert_tail(&rsc->sc_txq[i].tx_dirty_list, bf); 2291 bf->bf_in = in; 2292 rtw_dma_start(&rsc->sc_regs, i); 2293 2294 mutex_exit(&rsc->sc_txq[i].txbuf_lock); 2295 mutex_exit(&rsc->sc_txlock); 2296 2297 freemsg(mp); 2298 return (0); 2299 } 2300 2301 static mblk_t * 2302 rtw_m_tx(void *arg, mblk_t *mp) 2303 { 2304 rtw_softc_t *rsc = arg; 2305 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2306 mblk_t *next; 2307 2308 if (ic->ic_state != IEEE80211_S_RUN) { 2309 freemsgchain(mp); 2310 return (NULL); 2311 } 2312 2313 while (mp != NULL) { 2314 next = mp->b_next; 2315 mp->b_next = NULL; 2316 2317 if (rtw_send(ic, mp, IEEE80211_FC0_TYPE_DATA)) { 2318 mp->b_next = next; 2319 break; 2320 } 2321 mp = next; 2322 } 2323 2324 return (mp); 2325 2326 } 2327 2328 static void 2329 rtw_next_scan(void *arg) 2330 { 2331 ieee80211com_t *ic = arg; 2332 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2333 2334 rsc->sc_scan_id = 0; 2335 if (ic->ic_state == IEEE80211_S_SCAN) { 2336 RTW_DPRINTF(RTW_DEBUG_TUNE, "rtw_next_scan\n"); 2337 (void) ieee80211_next_scan(ic); 2338 } 2339 2340 } 2341 2342 static void 2343 rtw_join_bss(rtw_softc_t *rsc, uint8_t *bssid, uint16_t intval0) 2344 { 2345 uint16_t bcnitv, intval; 2346 int i; 2347 struct rtw_regs *regs = &rsc->sc_regs; 2348 2349 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 2350 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 2351 2352 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 2353 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2354 2355 RTW_WRITE8(regs, RTW_MSR, 0x8); /* sta mode link ok */ 2356 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK)); 2357 2358 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 2359 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK); 2360 RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 2361 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND)); 2362 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV)); 2363 2364 rtw_set_access(regs, RTW_ACCESS_NONE); 2365 2366 /* TBD WEP */ 2367 /* RTW_WRITE8(regs, RTW_SCR, 0); */ 2368 2369 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 1); 2370 } 2371 2372 /* 2373 * Set the starting transmit rate for a node. 2374 */ 2375 static void 2376 rtw_rate_ctl_start(rtw_softc_t *rsc, struct ieee80211_node *in) 2377 { 2378 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2379 int32_t srate; 2380 2381 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { 2382 /* 2383 * No fixed rate is requested. For 11b start with 2384 * the highest negotiated rate; otherwise, for 11g 2385 * and 11a, we start "in the middle" at 24Mb or 36Mb. 2386 */ 2387 srate = in->in_rates.ir_nrates - 1; 2388 if (ic->ic_curmode != IEEE80211_MODE_11B) { 2389 /* 2390 * Scan the negotiated rate set to find the 2391 * closest rate. 2392 */ 2393 /* NB: the rate set is assumed sorted */ 2394 for (; srate >= 0 && IEEE80211_RATE(srate) > 72; 2395 srate--) 2396 ; 2397 } 2398 } else { 2399 /* 2400 * A fixed rate is to be used; We know the rate is 2401 * there because the rate set is checked when the 2402 * station associates. 2403 */ 2404 /* NB: the rate set is assumed sorted */ 2405 srate = in->in_rates.ir_nrates - 1; 2406 for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate; 2407 srate--) 2408 ; 2409 } 2410 in->in_txrate = srate; 2411 } 2412 2413 2414 /* 2415 * Reset the rate control state for each 802.11 state transition. 2416 */ 2417 static void 2418 rtw_rate_ctl_reset(rtw_softc_t *rsc, enum ieee80211_state state) 2419 { 2420 ieee80211com_t *ic = &rsc->sc_ic; 2421 ieee80211_node_t *in; 2422 2423 if (ic->ic_opmode == IEEE80211_M_STA) { 2424 /* 2425 * Reset local xmit state; this is really only 2426 * meaningful when operating in station mode. 2427 */ 2428 in = (struct ieee80211_node *)ic->ic_bss; 2429 2430 if (state == IEEE80211_S_RUN) { 2431 rtw_rate_ctl_start(rsc, in); 2432 } else { 2433 in->in_txrate = 0; 2434 } 2435 } 2436 } 2437 2438 /* 2439 * Examine and potentially adjust the transmit rate. 2440 */ 2441 static void 2442 rtw_rate_ctl(void *arg) 2443 { 2444 ieee80211com_t *ic = (ieee80211com_t *)arg; 2445 rtw_softc_t *rsc = (rtw_softc_t *)ic; 2446 struct ieee80211_node *in = ic->ic_bss; 2447 struct ieee80211_rateset *rs = &in->in_rates; 2448 int32_t mod = 1, nrate, enough; 2449 2450 mutex_enter(&rsc->sc_genlock); 2451 enough = (rsc->sc_tx_ok + rsc->sc_tx_err) >= 600? 1 : 0; 2452 2453 /* err ratio is high -> down */ 2454 if (enough && rsc->sc_tx_ok < rsc->sc_tx_err) 2455 mod = -1; 2456 2457 nrate = in->in_txrate; 2458 switch (mod) { 2459 case -1: 2460 if (nrate > 0) { 2461 nrate--; 2462 } 2463 break; 2464 case 1: 2465 if (nrate + 1 < rs->ir_nrates) { 2466 nrate++; 2467 } 2468 break; 2469 } 2470 2471 if (nrate != in->in_txrate) 2472 in->in_txrate = nrate; 2473 rsc->sc_tx_ok = rsc->sc_tx_err = rsc->sc_tx_retr = 0; 2474 mutex_exit(&rsc->sc_genlock); 2475 if (ic->ic_state == IEEE80211_S_RUN) 2476 rsc->sc_ratectl_id = timeout(rtw_rate_ctl, ic, 2477 drv_usectohz(1000000)); 2478 } 2479 2480 static int32_t 2481 rtw_new_state(ieee80211com_t *ic, enum ieee80211_state nstate, int arg) 2482 { 2483 rtw_softc_t *rsc = (rtw_softc_t *)ic; 2484 int error; 2485 enum ieee80211_state ostate; 2486 2487 ostate = ic->ic_state; 2488 2489 RTW_DPRINTF(RTW_DEBUG_ATTACH, 2490 "rtw_new_state: ostate:0x%x, nstate:0x%x, opmode:0x%x\n", 2491 ostate, nstate, ic->ic_opmode); 2492 2493 2494 mutex_enter(&rsc->sc_genlock); 2495 if (rsc->sc_scan_id != 0) { 2496 (void) untimeout(rsc->sc_scan_id); 2497 rsc->sc_scan_id = 0; 2498 } 2499 if (rsc->sc_ratectl_id != 0) { 2500 (void) untimeout(rsc->sc_ratectl_id); 2501 rsc->sc_ratectl_id = 0; 2502 } 2503 rtw_rate_ctl_reset(rsc, nstate); 2504 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 2505 (void) rtw_pwrstate(rsc, RTW_ON); 2506 if (nstate != IEEE80211_S_INIT) { 2507 if ((error = rtw_tune(rsc)) != 0) { 2508 mutex_exit(&rsc->sc_genlock); 2509 return (error); 2510 } 2511 } 2512 switch (nstate) { 2513 case IEEE80211_S_INIT: 2514 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_INIT\n"); 2515 break; 2516 case IEEE80211_S_SCAN: 2517 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_SCAN\n"); 2518 rsc->sc_scan_id = timeout(rtw_next_scan, ic, 2519 drv_usectohz(200000)); 2520 rtw_set_nettype(rsc, IEEE80211_M_MONITOR); 2521 break; 2522 case IEEE80211_S_RUN: 2523 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_new_state: S_RUN\n"); 2524 switch (ic->ic_opmode) { 2525 case IEEE80211_M_HOSTAP: 2526 case IEEE80211_M_IBSS: 2527 rtw_set_nettype(rsc, IEEE80211_M_MONITOR); 2528 /* TBD */ 2529 /*FALLTHROUGH*/ 2530 case IEEE80211_M_AHDEMO: 2531 case IEEE80211_M_STA: 2532 RTW_DPRINTF(RTW_DEBUG_ATTACH, 2533 "rtw_new_state: sta\n"); 2534 rtw_join_bss(rsc, ic->ic_bss->in_bssid, 0); 2535 rsc->sc_ratectl_id = timeout(rtw_rate_ctl, ic, 2536 drv_usectohz(1000000)); 2537 break; 2538 case IEEE80211_M_MONITOR: 2539 break; 2540 } 2541 rtw_set_nettype(rsc, ic->ic_opmode); 2542 break; 2543 case IEEE80211_S_ASSOC: 2544 case IEEE80211_S_AUTH: 2545 break; 2546 } 2547 2548 mutex_exit(&rsc->sc_genlock); 2549 /* 2550 * Invoke the parent method to complete the work. 2551 */ 2552 error = rsc->sc_newstate(ic, nstate, arg); 2553 2554 return (error); 2555 } 2556 2557 static void 2558 rtw_intr_rx(rtw_softc_t *rsc) 2559 { 2560 #define IS_BEACON(__fc0) \ 2561 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\ 2562 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON)) 2563 /* 2564 * ratetbl[4] = {2, 4, 11, 22}; 2565 */ 2566 struct rtw_rxbuf *bf; 2567 struct rtw_rxdesc *ds; 2568 int hwrate, len, rssi; 2569 uint32_t hstat, hrssi, htsftl; 2570 int is_last, next, n = 0, i; 2571 struct ieee80211_frame *wh; 2572 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2573 mblk_t *mp; 2574 2575 RTW_DPRINTF(RTW_DEBUG_RECV, "%s rtw_intr_rx: enter ic_state=%x\n", 2576 __func__, rsc->sc_ic.ic_state); 2577 mutex_enter(&rsc->rxbuf_lock); 2578 next = rsc->rx_next; 2579 mutex_exit(&rsc->rxbuf_lock); 2580 for (i = 0; i < RTW_RXQLEN; i++) { 2581 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2582 RTW_DESC_OFFSET(hd_rx, next), 2583 sizeof (struct rtw_rxdesc), 2584 DDI_DMA_SYNC_FORKERNEL); 2585 n++; 2586 bf = rsc->rxbuf_h + next; 2587 ds = bf->rxdesc; 2588 hstat = (ds->rd_stat); 2589 hrssi = ds->rd_rssi; 2590 htsftl = ds->rd_tsftl; 2591 /* htsfth = ds->rd_tsfth; */ 2592 RTW_DPRINTF(RTW_DEBUG_RECV, "%s: stat=%x\n", __func__, hstat); 2593 /* still belongs to NIC */ 2594 if ((hstat & RTW_RXSTAT_OWN) != 0) { 2595 if (n > 1) { 2596 RTW_DPRINTF(RTW_DEBUG_RECV, 2597 "%s: n > 1\n", __func__); 2598 break; 2599 } 2600 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2601 RTW_DESC_OFFSET(hd_rx, 0), 2602 sizeof (struct rtw_rxdesc), 2603 DDI_DMA_SYNC_FORCPU); 2604 bf = rsc->rxbuf_h; 2605 ds = bf->rxdesc; 2606 hstat = (ds->rd_stat); 2607 if ((hstat & RTW_RXSTAT_OWN) != 0) 2608 break; 2609 next = 0 /* RTW_RXQLEN - 1 */; 2610 continue; 2611 } 2612 2613 rsc->sc_pktrcv64++; 2614 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 2615 RTW_DPRINTF(RTW_DEBUG_RECV, 2616 "rtw: DMA error/FIFO overflow %08x, " 2617 "rx descriptor %d\n", 2618 hstat & RTW_RXSTAT_IOERROR, next); 2619 goto next; 2620 } 2621 2622 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK); 2623 rsc->sc_bytercv64 += len; 2624 2625 /* CRC is included with the packet; trim it off. */ 2626 /* len -= IEEE80211_CRC_LEN; */ 2627 2628 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK); 2629 if (hwrate >= 4) { 2630 goto next; 2631 } 2632 2633 if ((hstat & RTW_RXSTAT_RES) != 0 && 2634 rsc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) { 2635 goto next; 2636 } 2637 2638 /* if bad flags, skip descriptor */ 2639 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 2640 RTW_DPRINTF(RTW_DEBUG_RECV, 2641 "rtw too many rx segments\n"); 2642 goto next; 2643 } 2644 2645 if (rsc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 2646 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI); 2647 else { 2648 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI); 2649 /* 2650 * TBD find out each front-end's LNA gain in the 2651 * front-end's units 2652 */ 2653 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 2654 rssi |= 0x80; 2655 } 2656 /* sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ); */ 2657 2658 2659 /* deal with the frame itself here */ 2660 mp = allocb(rsc->sc_dmabuf_size, BPRI_MED); 2661 if (mp == NULL) { 2662 cmn_err(CE_WARN, "rtw: alloc mblk error"); 2663 rsc->sc_norcvbuf++; 2664 return; 2665 } 2666 len -= IEEE80211_CRC_LEN; 2667 RTW_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORKERNEL); 2668 bcopy(bf->bf_dma.mem_va, mp->b_rptr, len); 2669 mp->b_wptr += len; 2670 wh = (struct ieee80211_frame *)mp->b_rptr; 2671 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2672 IEEE80211_FC0_TYPE_CTL) { 2673 cmn_err(CE_WARN, "TYPE CTL !!\n"); 2674 freemsg(mp); 2675 goto next; 2676 } 2677 (void) ieee80211_input(ic, mp, ic->ic_bss, rssi, htsftl); 2678 next: 2679 if (next == 63) 2680 is_last = 1; 2681 else 2682 is_last = 0; 2683 rtw_rxdesc_init(rsc, bf, next, is_last); 2684 2685 next = (next + 1)%RTW_RXQLEN; 2686 RTW_DPRINTF(RTW_DEBUG_RECV, "%s: next = %d\n", __func__, next); 2687 } 2688 mutex_enter(&rsc->rxbuf_lock); 2689 rsc->rx_next = next; 2690 mutex_exit(&rsc->rxbuf_lock); 2691 } 2692 2693 static void 2694 rtw_ring_recycling(rtw_softc_t *rsc, uint16_t isr, uint32_t pri) 2695 { 2696 struct rtw_txbuf *bf; 2697 struct rtw_txdesc *ds; 2698 uint32_t hstat; 2699 uint32_t head = 0; 2700 uint32_t cnt = 0, idx = 0; 2701 2702 mutex_enter(&rsc->sc_txq[pri].txbuf_lock); 2703 head = RTW_READ(&rsc->sc_regs, RTW_TNPDA); 2704 if (head == rsc->hw_go) { 2705 mutex_exit(&rsc->sc_txq[pri].txbuf_lock); 2706 return; 2707 } 2708 RTW_DPRINTF(RTW_DEBUG_XMIT, "rtw_ring_recycling: enter ic_state=%x\n", 2709 rsc->sc_ic.ic_state); 2710 2711 bf = list_head(&rsc->sc_txq[pri].tx_dirty_list); 2712 if (bf == NULL) { 2713 RTW_DPRINTF(RTW_DEBUG_XMIT, 2714 "rtw_ring_recycling: dirty bf[%d] NULL\n", pri); 2715 mutex_exit(&rsc->sc_txq[pri].txbuf_lock); 2716 return; 2717 } 2718 2719 while ((bf != NULL) && (rsc->hw_go != head)) { 2720 cnt++; 2721 idx = (rsc->hw_go - rsc->hw_start) / sizeof (struct rtw_txdesc); 2722 if (idx == 63) 2723 rsc->hw_go = rsc->hw_start; 2724 else 2725 rsc->hw_go += sizeof (struct rtw_txdesc); 2726 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2727 RTW_DESC_OFFSET(hd_txmd, idx), 2728 sizeof (struct rtw_txdesc), 2729 DDI_DMA_SYNC_FORCPU); 2730 2731 RTW_DPRINTF(RTW_DEBUG_XMIT, "Head = 0x%x\n", head); 2732 ds = bf->txdesc; 2733 hstat = (ds->td_stat); 2734 ds->td_len = ds->td_len & 0xfff; 2735 RTW_DPRINTF(RTW_DEBUG_XMIT, 2736 "%s rtw_ring_recycling: stat=%x, pri=%x\n", 2737 __func__, hstat, pri); 2738 if (hstat & RTW_TXSTAT_TOK) 2739 rsc->sc_tx_ok++; 2740 else { 2741 RTW_DPRINTF(RTW_DEBUG_XMIT, 2742 "TX err @%d, o %d, retry[%d], isr[0x%x], cnt %d\n", 2743 idx, (hstat & RTW_TXSTAT_OWN)?1:0, 2744 (hstat & RTW_TXSTAT_DRC_MASK), isr, cnt); 2745 if ((hstat & RTW_TXSTAT_DRC_MASK) <= 4) { 2746 rsc->sc_tx_ok++; 2747 } else { 2748 rsc->sc_tx_err++; 2749 } 2750 } 2751 rsc->sc_tx_retr += 2752 (hstat & RTW_TXSTAT_DRC_MASK); 2753 rsc->sc_xmtretry += 2754 (hstat & RTW_TXSTAT_DRC_MASK); 2755 list_remove(&rsc->sc_txq[pri].tx_dirty_list, bf); 2756 list_insert_tail(&rsc->sc_txq[pri].tx_free_list, 2757 bf); 2758 (rsc->sc_txq[pri].tx_nfree)++; 2759 if (rsc->sc_need_reschedule == 1) { 2760 mac_tx_update(rsc->sc_ic.ic_mach); 2761 rsc->sc_need_reschedule = 0; 2762 } 2763 RTW_DPRINTF(RTW_DEBUG_XMIT, 2764 "rtw_ring_recycling: nfree[%d]=%d\n", 2765 pri, rsc->sc_txq[pri].tx_nfree); 2766 bzero((uint8_t *)ds, sizeof (struct rtw_txdesc)); 2767 RTW_DMA_SYNC_DESC(rsc->sc_desc_dma, 2768 RTW_DESC_OFFSET(hd_txmd, idx), 2769 sizeof (struct rtw_txdesc), 2770 DDI_DMA_SYNC_FORDEV); 2771 bf = list_head(&rsc->sc_txq[pri].tx_dirty_list); 2772 } 2773 mutex_exit(&rsc->sc_txq[pri].txbuf_lock); 2774 } 2775 2776 static void 2777 rtw_intr_timeout(rtw_softc_t *rsc) 2778 { 2779 rtw_resume_ticks(rsc); 2780 } 2781 2782 static uint_t 2783 rtw_intr(caddr_t arg) 2784 { 2785 /* LINTED E_BAD_PTR_CAST_ALIGN */ 2786 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2787 struct rtw_regs *regs = &rsc->sc_regs; 2788 uint16_t isr = 0; 2789 2790 mutex_enter(&rsc->sc_genlock); 2791 isr = RTW_READ16(regs, RTW_ISR); 2792 RTW_WRITE16(regs, RTW_ISR, isr); 2793 2794 if (isr == 0) { 2795 mutex_exit(&rsc->sc_genlock); 2796 return (DDI_INTR_UNCLAIMED); 2797 } 2798 2799 #ifdef DEBUG 2800 #define PRINTINTR(flag) { \ 2801 if ((isr & flag) != 0) { \ 2802 RTW_DPRINTF(RTW_DEBUG_INTR, "|" #flag); \ 2803 } \ 2804 } 2805 2806 if ((rtw_dbg_flags & RTW_DEBUG_INTR) != 0 && isr != 0) { 2807 2808 RTW_DPRINTF(RTW_DEBUG_INTR, "rtw: reg[ISR] = %x", isr); 2809 2810 PRINTINTR(RTW_INTR_TXFOVW); 2811 PRINTINTR(RTW_INTR_TIMEOUT); 2812 PRINTINTR(RTW_INTR_BCNINT); 2813 PRINTINTR(RTW_INTR_ATIMINT); 2814 PRINTINTR(RTW_INTR_TBDER); 2815 PRINTINTR(RTW_INTR_TBDOK); 2816 PRINTINTR(RTW_INTR_THPDER); 2817 PRINTINTR(RTW_INTR_THPDOK); 2818 PRINTINTR(RTW_INTR_TNPDER); 2819 PRINTINTR(RTW_INTR_TNPDOK); 2820 PRINTINTR(RTW_INTR_RXFOVW); 2821 PRINTINTR(RTW_INTR_RDU); 2822 PRINTINTR(RTW_INTR_TLPDER); 2823 PRINTINTR(RTW_INTR_TLPDOK); 2824 PRINTINTR(RTW_INTR_RER); 2825 PRINTINTR(RTW_INTR_ROK); 2826 } 2827 #undef PRINTINTR 2828 #endif /* DEBUG */ 2829 2830 rsc->sc_intr++; 2831 2832 if ((isr & RTW_INTR_RX) != 0) { 2833 mutex_exit(&rsc->sc_genlock); 2834 rtw_intr_rx(rsc); 2835 mutex_enter(&rsc->sc_genlock); 2836 } 2837 if ((isr & RTW_INTR_TIMEOUT) != 0) 2838 rtw_intr_timeout(rsc); 2839 2840 if ((isr & RTW_INTR_TX) != 0) 2841 rtw_ring_recycling(rsc, isr, 1); 2842 mutex_exit(&rsc->sc_genlock); 2843 return (DDI_INTR_CLAIMED); 2844 } 2845 2846 static void 2847 rtw_stop(void *arg) 2848 { 2849 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2850 struct rtw_regs *regs = &rsc->sc_regs; 2851 2852 mutex_enter(&rsc->sc_genlock); 2853 rtw_disable_interrupts(regs); 2854 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 2855 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 2856 rsc->sc_invalid = 1; 2857 mutex_exit(&rsc->sc_genlock); 2858 } 2859 2860 static void 2861 rtw_m_stop(void *arg) 2862 { 2863 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2864 2865 (void) ieee80211_new_state(&rsc->sc_ic, IEEE80211_S_INIT, -1); 2866 rtw_stop(rsc); 2867 } 2868 2869 /* 2870 * quiesce(9E) entry point. 2871 * 2872 * This function is called when the system is single-threaded at high 2873 * PIL with preemption disabled. Therefore, this function must not be 2874 * blocked. 2875 * 2876 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 2877 * DDI_FAILURE indicates an error condition and should almost never happen. 2878 */ 2879 int 2880 rtw_quiesce(dev_info_t *dip) 2881 { 2882 rtw_softc_t *rsc = NULL; 2883 struct rtw_regs *regs; 2884 2885 rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(dip)); 2886 ASSERT(rsc != NULL); 2887 regs = &rsc->sc_regs; 2888 2889 rtw_dbg_flags = 0; 2890 rtw_disable_interrupts(regs); 2891 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 2892 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 2893 2894 return (DDI_SUCCESS); 2895 } 2896 2897 /* 2898 * callback functions for /get/set properties 2899 */ 2900 static int 2901 rtw_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2902 uint_t wldp_length, const void *wldp_buf) 2903 { 2904 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2905 struct ieee80211com *ic = &rsc->sc_ic; 2906 int err; 2907 2908 err = ieee80211_setprop(ic, pr_name, wldp_pr_num, 2909 wldp_length, wldp_buf); 2910 if (err == ENETRESET) { 2911 if (ic->ic_des_esslen && (rsc->sc_invalid == 0)) { 2912 (void) rtw_init(rsc); 2913 (void) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2914 } 2915 err = 0; 2916 } 2917 return (err); 2918 } 2919 2920 static int 2921 rtw_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2922 uint_t wldp_length, void *wldp_buf) 2923 { 2924 rtw_softc_t *rsc = arg; 2925 int err; 2926 2927 err = ieee80211_getprop(&rsc->sc_ic, pr_name, wldp_pr_num, 2928 wldp_length, wldp_buf); 2929 2930 return (err); 2931 } 2932 2933 static void 2934 rtw_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num, 2935 mac_prop_info_handle_t prh) 2936 { 2937 rtw_softc_t *rsc = arg; 2938 2939 ieee80211_propinfo(&rsc->sc_ic, pr_name, wldp_pr_num, prh); 2940 } 2941 2942 static int 2943 rtw_m_start(void *arg) 2944 { 2945 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2946 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2947 int ret; 2948 #ifdef DEBUG 2949 rtw_print_regs(&rsc->sc_regs, "rtw", "rtw_start"); 2950 #endif 2951 2952 ret = rtw_init(rsc); 2953 if (ret) { 2954 cmn_err(CE_WARN, "rtw: failed to do rtw_init\n"); 2955 return (EIO); 2956 } 2957 (void) ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2958 return (0); 2959 } 2960 2961 2962 static int 2963 rtw_m_unicst(void *arg, const uint8_t *macaddr) 2964 { 2965 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2966 ieee80211com_t *ic = (ieee80211com_t *)rsc; 2967 struct rtw_regs *regs = &rsc->sc_regs; 2968 uint32_t t; 2969 2970 mutex_enter(&rsc->sc_genlock); 2971 bcopy(macaddr, ic->ic_macaddr, 6); 2972 t = ((*macaddr)<<24) | ((*(macaddr + 1))<<16) | 2973 ((*(macaddr + 2))<<8) | (*(macaddr + 3)); 2974 RTW_WRITE(regs, RTW_IDR0, ntohl(t)); 2975 t = ((*(macaddr + 4))<<24) | ((*(macaddr + 5))<<16); 2976 RTW_WRITE(regs, RTW_IDR1, ntohl(t)); 2977 mutex_exit(&rsc->sc_genlock); 2978 return (0); 2979 } 2980 2981 static int 2982 rtw_m_promisc(void *arg, boolean_t on) 2983 { 2984 rtw_softc_t *rsc = (rtw_softc_t *)arg; 2985 struct rtw_regs *regs = &rsc->sc_regs; 2986 2987 mutex_enter(&rsc->sc_genlock); 2988 2989 if (on) 2990 rsc->sc_rcr |= RTW_RCR_PROMIC; 2991 else 2992 rsc->sc_rcr &= ~RTW_RCR_PROMIC; 2993 2994 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 2995 2996 mutex_exit(&rsc->sc_genlock); 2997 return (0); 2998 } 2999 3000 static int 3001 rtw_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr) 3002 { 3003 rtw_softc_t *rsc = (rtw_softc_t *)arg; 3004 struct rtw_regs *regs = &rsc->sc_regs; 3005 uint32_t t; 3006 3007 mutex_enter(&rsc->sc_genlock); 3008 if (add) { 3009 rsc->sc_rcr |= RTW_RCR_AM; 3010 t = ((*macaddr)<<24) | ((*(macaddr + 1))<<16) | 3011 ((*(macaddr + 2))<<8) | (*(macaddr + 3)); 3012 RTW_WRITE(regs, RTW_MAR0, ntohl(t)); 3013 t = ((*(macaddr + 4))<<24) | ((*(macaddr + 5))<<16); 3014 RTW_WRITE(regs, RTW_MAR1, ntohl(t)); 3015 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 3016 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); 3017 } else { 3018 rsc->sc_rcr &= ~RTW_RCR_AM; 3019 RTW_WRITE(regs, RTW_MAR0, 0); 3020 RTW_WRITE(regs, RTW_MAR1, 0); 3021 RTW_WRITE(regs, RTW_RCR, rsc->sc_rcr); 3022 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); 3023 } 3024 mutex_exit(&rsc->sc_genlock); 3025 return (0); 3026 } 3027 3028 static void 3029 rtw_m_ioctl(void* arg, queue_t *wq, mblk_t *mp) 3030 { 3031 rtw_softc_t *rsc = arg; 3032 struct ieee80211com *ic = &rsc->sc_ic; 3033 int err; 3034 3035 err = ieee80211_ioctl(ic, wq, mp); 3036 if (err == ENETRESET) { 3037 if (ic->ic_des_esslen && (rsc->sc_invalid == 0)) { 3038 (void) rtw_init(rsc); 3039 (void) ieee80211_new_state(ic, 3040 IEEE80211_S_SCAN, -1); 3041 } 3042 } 3043 } 3044 3045 static int 3046 rtw_m_stat(void *arg, uint_t stat, uint64_t *val) 3047 { 3048 rtw_softc_t *rsc = (rtw_softc_t *)arg; 3049 ieee80211com_t *ic = &rsc->sc_ic; 3050 struct ieee80211_node *in = 0; 3051 struct ieee80211_rateset *rs = 0; 3052 3053 mutex_enter(&rsc->sc_genlock); 3054 switch (stat) { 3055 case MAC_STAT_IFSPEED: 3056 in = ic->ic_bss; 3057 rs = &in->in_rates; 3058 *val = ((ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) ? 3059 (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) 3060 : ic->ic_fixed_rate) / 2 * 1000000; 3061 break; 3062 case MAC_STAT_NOXMTBUF: 3063 *val = rsc->sc_noxmtbuf; 3064 break; 3065 case MAC_STAT_NORCVBUF: 3066 *val = rsc->sc_norcvbuf; 3067 break; 3068 case MAC_STAT_RBYTES: 3069 *val = rsc->sc_bytercv64; 3070 break; 3071 case MAC_STAT_IPACKETS: 3072 *val = rsc->sc_pktrcv64; 3073 break; 3074 case MAC_STAT_OBYTES: 3075 *val = rsc->sc_bytexmt64; 3076 break; 3077 case MAC_STAT_OPACKETS: 3078 *val = rsc->sc_pktxmt64; 3079 break; 3080 case WIFI_STAT_TX_RETRANS: 3081 *val = rsc->sc_xmtretry; 3082 break; 3083 case WIFI_STAT_TX_FRAGS: 3084 case WIFI_STAT_MCAST_TX: 3085 case WIFI_STAT_RTS_SUCCESS: 3086 case WIFI_STAT_RTS_FAILURE: 3087 case WIFI_STAT_ACK_FAILURE: 3088 case WIFI_STAT_RX_FRAGS: 3089 case WIFI_STAT_MCAST_RX: 3090 case WIFI_STAT_RX_DUPS: 3091 mutex_exit(&rsc->sc_genlock); 3092 return (ieee80211_stat(ic, stat, val)); 3093 default: 3094 *val = 0; 3095 break; 3096 } 3097 mutex_exit(&rsc->sc_genlock); 3098 3099 return (0); 3100 } 3101 3102 3103 static void 3104 rtw_mutex_destroy(rtw_softc_t *rsc) 3105 { 3106 int i; 3107 3108 mutex_destroy(&rsc->rxbuf_lock); 3109 mutex_destroy(&rsc->sc_txlock); 3110 for (i = 0; i < RTW_NTXPRI; i++) { 3111 mutex_destroy(&rsc->sc_txq[RTW_NTXPRI - 1 - i].txbuf_lock); 3112 } 3113 mutex_destroy(&rsc->sc_genlock); 3114 } 3115 3116 static int 3117 rtw_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd) 3118 { 3119 rtw_softc_t *rsc; 3120 ieee80211com_t *ic; 3121 uint8_t csz; 3122 uint32_t i; 3123 uint16_t vendor_id, device_id, command; 3124 int32_t err; 3125 char strbuf[32]; 3126 wifi_data_t wd = { 0 }; 3127 mac_register_t *macp; 3128 int instance = ddi_get_instance(devinfo); 3129 3130 switch (cmd) { 3131 case DDI_ATTACH: 3132 break; 3133 case DDI_RESUME: 3134 rsc = ddi_get_soft_state(rtw_soft_state_p, 3135 ddi_get_instance(devinfo)); 3136 ASSERT(rsc != NULL); 3137 mutex_enter(&rsc->sc_genlock); 3138 rsc->sc_flags &= ~RTW_F_SUSPEND; 3139 mutex_exit(&rsc->sc_genlock); 3140 if ((rsc->sc_flags & RTW_F_PLUMBED)) { 3141 err = rtw_init(rsc); 3142 if (err == 0) { 3143 mutex_enter(&rsc->sc_genlock); 3144 rsc->sc_flags &= ~RTW_F_PLUMBED; 3145 mutex_exit(&rsc->sc_genlock); 3146 } 3147 } 3148 return (DDI_SUCCESS); 3149 default: 3150 return (DDI_FAILURE); 3151 } 3152 3153 if (ddi_soft_state_zalloc(rtw_soft_state_p, 3154 ddi_get_instance(devinfo)) != DDI_SUCCESS) { 3155 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3156 "Unable to alloc softstate\n"); 3157 return (DDI_FAILURE); 3158 } 3159 3160 rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(devinfo)); 3161 ic = &rsc->sc_ic; 3162 rsc->sc_dev = devinfo; 3163 3164 err = ddi_regs_map_setup(devinfo, 0, (caddr_t *)&rsc->sc_cfg_base, 0, 0, 3165 &rtw_reg_accattr, &rsc->sc_cfg_handle); 3166 if (err != DDI_SUCCESS) { 3167 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3168 "ddi_regs_map_setup() failed"); 3169 goto attach_fail0; 3170 } 3171 csz = ddi_get8(rsc->sc_cfg_handle, 3172 (uint8_t *)(rsc->sc_cfg_base + PCI_CONF_CACHE_LINESZ)); 3173 if (!csz) 3174 csz = 16; 3175 rsc->sc_cachelsz = csz << 2; 3176 vendor_id = ddi_get16(rsc->sc_cfg_handle, 3177 (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_VENID)); 3178 device_id = ddi_get16(rsc->sc_cfg_handle, 3179 (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_DEVID)); 3180 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): vendor 0x%x, " 3181 "device id 0x%x, cache size %d\n", vendor_id, device_id, csz); 3182 3183 /* 3184 * Enable response to memory space accesses, 3185 * and enabe bus master. 3186 */ 3187 command = PCI_COMM_MAE | PCI_COMM_ME; 3188 ddi_put16(rsc->sc_cfg_handle, 3189 (uint16_t *)((uintptr_t)rsc->sc_cfg_base + PCI_CONF_COMM), command); 3190 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3191 "set command reg to 0x%x \n", command); 3192 3193 ddi_put8(rsc->sc_cfg_handle, 3194 (uint8_t *)(rsc->sc_cfg_base + PCI_CONF_LATENCY_TIMER), 0xa8); 3195 3196 ddi_regs_map_free(&rsc->sc_cfg_handle); 3197 3198 err = ddi_regs_map_setup(devinfo, 2, (caddr_t *)&rsc->sc_regs.r_base, 3199 0, 0, &rtw_reg_accattr, &rsc->sc_regs.r_handle); 3200 if (err != DDI_SUCCESS) { 3201 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3202 "ddi_regs_map_setup() failed"); 3203 goto attach_fail0; 3204 } 3205 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: r_base=%x, r_handle=%x\n", 3206 rsc->sc_regs.r_base, rsc->sc_regs.r_handle); 3207 3208 err = rtw_dma_init(devinfo, rsc); 3209 if (err != DDI_SUCCESS) { 3210 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3211 "failed to init dma: %d\n", err); 3212 goto attach_fail1; 3213 } 3214 3215 /* 3216 * Stop the transmit and receive processes. First stop DMA, 3217 * then disable receiver and transmitter. 3218 */ 3219 RTW_WRITE8(&rsc->sc_regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 3220 rtw_io_enable(rsc, RTW_CR_RE | RTW_CR_TE, 0); 3221 3222 /* Reset the chip to a known state. */ 3223 if (rtw_reset(rsc) != 0) { 3224 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3225 "failed to reset\n"); 3226 goto attach_fail2; 3227 } 3228 rsc->sc_rcr = RTW_READ(&rsc->sc_regs, RTW_RCR); 3229 3230 if ((rsc->sc_rcr & RTW_RCR_9356SEL) != 0) 3231 rsc->sc_flags |= RTW_F_9356SROM; 3232 3233 if (rtw_srom_read(&rsc->sc_regs, rsc->sc_flags, &rsc->sc_srom, 3234 "rtw") != 0) { 3235 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3236 "failed to read srom\n"); 3237 goto attach_fail2; 3238 } 3239 3240 if (rtw_srom_parse(&rsc->sc_srom, &rsc->sc_flags, &rsc->sc_csthr, 3241 &rsc->sc_rfchipid, &rsc->sc_rcr, &rsc->sc_locale, 3242 "rtw") != 0) { 3243 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw_attach():" 3244 " malformed serial ROM\n"); 3245 goto attach_fail3; 3246 } 3247 3248 RTW_DPRINTF(RTW_DEBUG_PHY, "rtw: %s PHY\n", 3249 ((rsc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"); 3250 3251 3252 rsc->sc_rf = rtw_rf_attach(rsc, rsc->sc_rfchipid, 3253 rsc->sc_flags & RTW_F_DIGPHY); 3254 3255 if (rsc->sc_rf == NULL) { 3256 cmn_err(CE_WARN, "rtw: rtw_attach(): could not attach RF\n"); 3257 goto attach_fail3; 3258 } 3259 rsc->sc_phydelay = rtw_check_phydelay(&rsc->sc_regs, rsc->sc_rcr); 3260 3261 RTW_DPRINTF(RTW_DEBUG_ATTACH, 3262 "rtw: PHY delay %d\n", rsc->sc_phydelay); 3263 3264 if (rsc->sc_locale == RTW_LOCALE_UNKNOWN) 3265 rtw_identify_country(&rsc->sc_regs, &rsc->sc_locale, 3266 "rtw"); 3267 3268 rtw_init_channels(rsc->sc_locale, &rsc->sc_ic.ic_sup_channels, 3269 "rtw"); 3270 3271 rtw_set80211props(ic); 3272 3273 if (rtw_identify_sta(&rsc->sc_regs, ic->ic_macaddr, 3274 "rtw") != 0) 3275 goto attach_fail4; 3276 3277 ic->ic_xmit = rtw_send; 3278 ieee80211_attach(ic); 3279 3280 rsc->sc_newstate = ic->ic_newstate; 3281 ic->ic_newstate = rtw_new_state; 3282 ieee80211_media_init(ic); 3283 ic->ic_def_txkey = 0; 3284 3285 if (ddi_get_iblock_cookie(devinfo, 0, &(rsc->sc_iblock)) 3286 != DDI_SUCCESS) { 3287 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3288 "Can not get iblock cookie for INT\n"); 3289 goto attach_fail5; 3290 } 3291 3292 mutex_init(&rsc->sc_genlock, NULL, MUTEX_DRIVER, rsc->sc_iblock); 3293 for (i = 0; i < RTW_NTXPRI; i++) { 3294 mutex_init(&rsc->sc_txq[i].txbuf_lock, NULL, MUTEX_DRIVER, 3295 rsc->sc_iblock); 3296 } 3297 mutex_init(&rsc->rxbuf_lock, NULL, MUTEX_DRIVER, rsc->sc_iblock); 3298 mutex_init(&rsc->sc_txlock, NULL, MUTEX_DRIVER, rsc->sc_iblock); 3299 3300 if (ddi_add_intr(devinfo, 0, &rsc->sc_iblock, NULL, rtw_intr, 3301 (caddr_t)(rsc)) != DDI_SUCCESS) { 3302 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3303 "Can not add intr for rtw driver\n"); 3304 goto attach_fail7; 3305 } 3306 3307 /* 3308 * Provide initial settings for the WiFi plugin; whenever this 3309 * information changes, we need to call mac_plugindata_update() 3310 */ 3311 wd.wd_opmode = ic->ic_opmode; 3312 wd.wd_secalloc = WIFI_SEC_NONE; 3313 IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid); 3314 3315 if ((macp = mac_alloc(MAC_VERSION)) == NULL) { 3316 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3317 "MAC version mismatch\n"); 3318 goto attach_fail8; 3319 } 3320 3321 macp->m_type_ident = MAC_PLUGIN_IDENT_WIFI; 3322 macp->m_driver = rsc; 3323 macp->m_dip = devinfo; 3324 macp->m_src_addr = ic->ic_macaddr; 3325 macp->m_callbacks = &rtw_m_callbacks; 3326 macp->m_min_sdu = 0; 3327 macp->m_max_sdu = IEEE80211_MTU; 3328 macp->m_pdata = &wd; 3329 macp->m_pdata_size = sizeof (wd); 3330 3331 err = mac_register(macp, &ic->ic_mach); 3332 mac_free(macp); 3333 if (err != 0) { 3334 RTW_DPRINTF(RTW_DEBUG_ATTACH, "rtw: rtw_attach(): " 3335 "mac_register err %x\n", err); 3336 goto attach_fail8; 3337 } 3338 3339 /* Create minor node of type DDI_NT_NET_WIFI */ 3340 (void) snprintf(strbuf, sizeof (strbuf), "%s%d", 3341 "rtw", instance); 3342 err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR, 3343 instance + 1, DDI_NT_NET_WIFI, 0); 3344 if (err != DDI_SUCCESS) { 3345 RTW_DPRINTF(RTW_DEBUG_ATTACH, "WARN: rtw: rtw_attach(): " 3346 "Create minor node failed - %d\n", err); 3347 goto attach_fail9; 3348 } 3349 mac_link_update(ic->ic_mach, LINK_STATE_DOWN); 3350 rsc->sc_flags |= RTW_F_ATTACHED; 3351 rsc->sc_need_reschedule = 0; 3352 rsc->sc_invalid = 1; 3353 return (DDI_SUCCESS); 3354 attach_fail9: 3355 (void) mac_disable(ic->ic_mach); 3356 (void) mac_unregister(ic->ic_mach); 3357 attach_fail8: 3358 ddi_remove_intr(devinfo, 0, rsc->sc_iblock); 3359 attach_fail7: 3360 attach_fail6: 3361 rtw_mutex_destroy(rsc); 3362 attach_fail5: 3363 ieee80211_detach(ic); 3364 attach_fail4: 3365 rtw_rf_destroy(rsc->sc_rf); 3366 attach_fail3: 3367 rtw_srom_free(&rsc->sc_srom); 3368 attach_fail2: 3369 rtw_dma_free(rsc); 3370 attach_fail1: 3371 ddi_regs_map_free(&rsc->sc_regs.r_handle); 3372 attach_fail0: 3373 ddi_soft_state_free(rtw_soft_state_p, ddi_get_instance(devinfo)); 3374 return (DDI_FAILURE); 3375 } 3376 3377 static int32_t 3378 rtw_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) 3379 { 3380 rtw_softc_t *rsc; 3381 3382 rsc = ddi_get_soft_state(rtw_soft_state_p, ddi_get_instance(devinfo)); 3383 ASSERT(rsc != NULL); 3384 3385 switch (cmd) { 3386 case DDI_DETACH: 3387 break; 3388 case DDI_SUSPEND: 3389 ieee80211_new_state(&rsc->sc_ic, IEEE80211_S_INIT, -1); 3390 mutex_enter(&rsc->sc_genlock); 3391 rsc->sc_flags |= RTW_F_SUSPEND; 3392 mutex_exit(&rsc->sc_genlock); 3393 if (rsc->sc_invalid == 0) { 3394 rtw_stop(rsc); 3395 mutex_enter(&rsc->sc_genlock); 3396 rsc->sc_flags |= RTW_F_PLUMBED; 3397 mutex_exit(&rsc->sc_genlock); 3398 } 3399 return (DDI_SUCCESS); 3400 default: 3401 return (DDI_FAILURE); 3402 } 3403 if (!(rsc->sc_flags & RTW_F_ATTACHED)) 3404 return (DDI_FAILURE); 3405 3406 if (mac_disable(rsc->sc_ic.ic_mach) != 0) 3407 return (DDI_FAILURE); 3408 3409 /* free intterrupt resources */ 3410 ddi_remove_intr(devinfo, 0, rsc->sc_iblock); 3411 3412 rtw_mutex_destroy(rsc); 3413 ieee80211_detach((ieee80211com_t *)rsc); 3414 /* 3415 * Unregister from the MAC layer subsystem 3416 */ 3417 (void) mac_unregister(rsc->sc_ic.ic_mach); 3418 3419 rtw_rf_destroy(rsc->sc_rf); 3420 rtw_srom_free(&rsc->sc_srom); 3421 rtw_dma_free(rsc); 3422 ddi_remove_minor_node(devinfo, NULL); 3423 ddi_regs_map_free(&rsc->sc_regs.r_handle); 3424 3425 ddi_soft_state_free(rtw_soft_state_p, ddi_get_instance(devinfo)); 3426 3427 return (DDI_SUCCESS); 3428 }