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