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