1 /* $NetBSD: rtw.c,v 1.43 2005/01/31 02:56:49 thorpej Exp $ */ 2 /*- 3 * Copyright (c) 2004, 2005 David Young. All rights reserved. 4 * 5 * Programmed for NetBSD by David Young. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of David Young may not be used to endorse or promote 16 * products derived from this software without specific prior 17 * written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 23 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 25 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 * OF SUCH DAMAGE. 31 */ 32 /* 33 * Device driver for the Realtek RTL8180 802.11 MAC/BBP. 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.43 2005/01/31 02:56:49 thorpej Exp $"); 38 39 #include "bpfilter.h" 40 41 #include <sys/param.h> 42 #include <sys/sysctl.h> 43 #include <sys/systm.h> 44 #include <sys/callout.h> 45 #include <sys/mbuf.h> 46 #include <sys/malloc.h> 47 #include <sys/kernel.h> 48 #include <sys/time.h> 49 #include <sys/types.h> 50 51 #include <machine/endian.h> 52 #include <machine/bus.h> 53 #include <machine/intr.h> /* splnet */ 54 55 #include <uvm/uvm_extern.h> 56 57 #include <net/if.h> 58 #include <net/if_media.h> 59 #include <net/if_ether.h> 60 61 #include <net80211/ieee80211_var.h> 62 #include <net80211/ieee80211_compat.h> 63 #include <net80211/ieee80211_radiotap.h> 64 65 #if NBPFILTER > 0 66 #include <net/bpf.h> 67 #endif 68 69 #include <dev/ic/rtwreg.h> 70 #include <dev/ic/rtwvar.h> 71 #include <dev/ic/rtwphyio.h> 72 #include <dev/ic/rtwphy.h> 73 74 #include <dev/ic/smc93cx6var.h> 75 76 #define KASSERT2(__cond, __msg) \ 77 do { \ 78 if (!(__cond)) \ 79 panic __msg ; \ 80 } while (0) 81 82 int rtw_rfprog_fallback = 0; 83 int rtw_host_rfio = 0; 84 85 #ifdef RTW_DEBUG 86 int rtw_debug = 0; 87 int rtw_rxbufs_limit = RTW_RXQLEN; 88 #endif /* RTW_DEBUG */ 89 90 #define NEXT_ATTACH_STATE(sc, state) do { \ 91 DPRINTF(sc, RTW_DEBUG_ATTACH, \ 92 ("%s: attach state %s\n", __func__, #state)); \ 93 sc->sc_attach_state = state; \ 94 } while (0) 95 96 int rtw_dwelltime = 200; /* milliseconds */ 97 98 static void rtw_start(struct ifnet *); 99 100 static void rtw_led_attach(struct rtw_softc *); 101 static void rtw_led_init(struct rtw_regs *); 102 static void rtw_led_slowblink(void *); 103 static void rtw_led_fastblink(void *); 104 static void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int); 105 106 static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO); 107 static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO); 108 #ifdef RTW_DEBUG 109 static void rtw_print_txdesc(struct rtw_softc *, const char *, 110 struct rtw_txsoft *, struct rtw_txdesc_blk *, int); 111 static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO); 112 static int rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_PROTO); 113 #endif /* RTW_DEBUG */ 114 115 /* 116 * Setup sysctl(3) MIB, hw.rtw.* 117 * 118 * TBD condition CTLFLAG_PERMANENT on being an LKM or not 119 */ 120 SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup") 121 { 122 int rc; 123 struct sysctlnode *cnode, *rnode; 124 125 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 126 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 127 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) 128 goto err; 129 130 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 131 CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw", 132 "Realtek RTL818x 802.11 controls", 133 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 134 goto err; 135 136 #ifdef RTW_DEBUG 137 /* control debugging printfs */ 138 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 139 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 140 "debug", SYSCTL_DESCR("Enable RTL818x debugging output"), 141 rtw_sysctl_verify_debug, 0, &rtw_debug, 0, 142 CTL_CREATE, CTL_EOL)) != 0) 143 goto err; 144 145 /* Limit rx buffers, for simulating resource exhaustion. */ 146 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 147 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 148 "rxbufs_limit", 149 SYSCTL_DESCR("Set rx buffers limit"), 150 rtw_sysctl_verify_rxbufs_limit, 0, &rtw_rxbufs_limit, 0, 151 CTL_CREATE, CTL_EOL)) != 0) 152 goto err; 153 154 #endif /* RTW_DEBUG */ 155 /* set fallback RF programming method */ 156 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 157 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 158 "rfprog_fallback", 159 SYSCTL_DESCR("Set fallback RF programming method"), 160 rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0, 161 CTL_CREATE, CTL_EOL)) != 0) 162 goto err; 163 164 /* force host to control RF I/O bus */ 165 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 166 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 167 "host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"), 168 rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0, 169 CTL_CREATE, CTL_EOL)) != 0) 170 goto err; 171 172 return; 173 err: 174 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 175 } 176 177 static int 178 rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper) 179 { 180 int error, t; 181 struct sysctlnode node; 182 183 node = *rnode; 184 t = *(int*)rnode->sysctl_data; 185 node.sysctl_data = &t; 186 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 187 if (error || newp == NULL) 188 return (error); 189 190 if (t < lower || t > upper) 191 return (EINVAL); 192 193 *(int*)rnode->sysctl_data = t; 194 195 return (0); 196 } 197 198 static int 199 rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS) 200 { 201 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 202 MASK_AND_RSHIFT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK)); 203 } 204 205 static int 206 rtw_sysctl_verify_rfio(SYSCTLFN_ARGS) 207 { 208 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, 1); 209 } 210 211 #ifdef RTW_DEBUG 212 static int 213 rtw_sysctl_verify_debug(SYSCTLFN_ARGS) 214 { 215 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, RTW_DEBUG_MAX); 216 } 217 218 static int 219 rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_ARGS) 220 { 221 return rtw_sysctl_verify(SYSCTLFN_CALL(rnode), 0, RTW_RXQLEN); 222 } 223 224 static void 225 rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where) 226 { 227 #define PRINTREG32(sc, reg) \ 228 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 229 ("%s: reg[ " #reg " / %03x ] = %08x\n", \ 230 dvname, reg, RTW_READ(regs, reg))) 231 232 #define PRINTREG16(sc, reg) \ 233 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 234 ("%s: reg[ " #reg " / %03x ] = %04x\n", \ 235 dvname, reg, RTW_READ16(regs, reg))) 236 237 #define PRINTREG8(sc, reg) \ 238 RTW_DPRINTF(RTW_DEBUG_REGDUMP, \ 239 ("%s: reg[ " #reg " / %03x ] = %02x\n", \ 240 dvname, reg, RTW_READ8(regs, reg))) 241 242 RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where)); 243 244 PRINTREG32(regs, RTW_IDR0); 245 PRINTREG32(regs, RTW_IDR1); 246 PRINTREG32(regs, RTW_MAR0); 247 PRINTREG32(regs, RTW_MAR1); 248 PRINTREG32(regs, RTW_TSFTRL); 249 PRINTREG32(regs, RTW_TSFTRH); 250 PRINTREG32(regs, RTW_TLPDA); 251 PRINTREG32(regs, RTW_TNPDA); 252 PRINTREG32(regs, RTW_THPDA); 253 PRINTREG32(regs, RTW_TCR); 254 PRINTREG32(regs, RTW_RCR); 255 PRINTREG32(regs, RTW_TINT); 256 PRINTREG32(regs, RTW_TBDA); 257 PRINTREG32(regs, RTW_ANAPARM); 258 PRINTREG32(regs, RTW_BB); 259 PRINTREG32(regs, RTW_PHYCFG); 260 PRINTREG32(regs, RTW_WAKEUP0L); 261 PRINTREG32(regs, RTW_WAKEUP0H); 262 PRINTREG32(regs, RTW_WAKEUP1L); 263 PRINTREG32(regs, RTW_WAKEUP1H); 264 PRINTREG32(regs, RTW_WAKEUP2LL); 265 PRINTREG32(regs, RTW_WAKEUP2LH); 266 PRINTREG32(regs, RTW_WAKEUP2HL); 267 PRINTREG32(regs, RTW_WAKEUP2HH); 268 PRINTREG32(regs, RTW_WAKEUP3LL); 269 PRINTREG32(regs, RTW_WAKEUP3LH); 270 PRINTREG32(regs, RTW_WAKEUP3HL); 271 PRINTREG32(regs, RTW_WAKEUP3HH); 272 PRINTREG32(regs, RTW_WAKEUP4LL); 273 PRINTREG32(regs, RTW_WAKEUP4LH); 274 PRINTREG32(regs, RTW_WAKEUP4HL); 275 PRINTREG32(regs, RTW_WAKEUP4HH); 276 PRINTREG32(regs, RTW_DK0); 277 PRINTREG32(regs, RTW_DK1); 278 PRINTREG32(regs, RTW_DK2); 279 PRINTREG32(regs, RTW_DK3); 280 PRINTREG32(regs, RTW_RETRYCTR); 281 PRINTREG32(regs, RTW_RDSAR); 282 PRINTREG32(regs, RTW_FER); 283 PRINTREG32(regs, RTW_FEMR); 284 PRINTREG32(regs, RTW_FPSR); 285 PRINTREG32(regs, RTW_FFER); 286 287 /* 16-bit registers */ 288 PRINTREG16(regs, RTW_BRSR); 289 PRINTREG16(regs, RTW_IMR); 290 PRINTREG16(regs, RTW_ISR); 291 PRINTREG16(regs, RTW_BCNITV); 292 PRINTREG16(regs, RTW_ATIMWND); 293 PRINTREG16(regs, RTW_BINTRITV); 294 PRINTREG16(regs, RTW_ATIMTRITV); 295 PRINTREG16(regs, RTW_CRC16ERR); 296 PRINTREG16(regs, RTW_CRC0); 297 PRINTREG16(regs, RTW_CRC1); 298 PRINTREG16(regs, RTW_CRC2); 299 PRINTREG16(regs, RTW_CRC3); 300 PRINTREG16(regs, RTW_CRC4); 301 PRINTREG16(regs, RTW_CWR); 302 303 /* 8-bit registers */ 304 PRINTREG8(regs, RTW_CR); 305 PRINTREG8(regs, RTW_9346CR); 306 PRINTREG8(regs, RTW_CONFIG0); 307 PRINTREG8(regs, RTW_CONFIG1); 308 PRINTREG8(regs, RTW_CONFIG2); 309 PRINTREG8(regs, RTW_MSR); 310 PRINTREG8(regs, RTW_CONFIG3); 311 PRINTREG8(regs, RTW_CONFIG4); 312 PRINTREG8(regs, RTW_TESTR); 313 PRINTREG8(regs, RTW_PSR); 314 PRINTREG8(regs, RTW_SCR); 315 PRINTREG8(regs, RTW_PHYDELAY); 316 PRINTREG8(regs, RTW_CRCOUNT); 317 PRINTREG8(regs, RTW_PHYADDR); 318 PRINTREG8(regs, RTW_PHYDATAW); 319 PRINTREG8(regs, RTW_PHYDATAR); 320 PRINTREG8(regs, RTW_CONFIG5); 321 PRINTREG8(regs, RTW_TPPOLL); 322 323 PRINTREG16(regs, RTW_BSSID16); 324 PRINTREG32(regs, RTW_BSSID32); 325 #undef PRINTREG32 326 #undef PRINTREG16 327 #undef PRINTREG8 328 } 329 #endif /* RTW_DEBUG */ 330 331 void 332 rtw_continuous_tx_enable(struct rtw_softc *sc, int enable) 333 { 334 struct rtw_regs *regs = &sc->sc_regs; 335 336 uint32_t tcr; 337 tcr = RTW_READ(regs, RTW_TCR); 338 tcr &= ~RTW_TCR_LBK_MASK; 339 if (enable) 340 tcr |= RTW_TCR_LBK_CONT; 341 else 342 tcr |= RTW_TCR_LBK_NORMAL; 343 RTW_WRITE(regs, RTW_TCR, tcr); 344 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 345 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 346 rtw_txdac_enable(sc, !enable); 347 rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */ 348 rtw_set_access(regs, RTW_ACCESS_NONE); 349 } 350 351 #ifdef RTW_DEBUG 352 static const char * 353 rtw_access_string(enum rtw_access access) 354 { 355 switch (access) { 356 case RTW_ACCESS_NONE: 357 return "none"; 358 case RTW_ACCESS_CONFIG: 359 return "config"; 360 case RTW_ACCESS_ANAPARM: 361 return "anaparm"; 362 default: 363 return "unknown"; 364 } 365 } 366 #endif /* RTW_DEBUG */ 367 368 static void 369 rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess) 370 { 371 KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM); 372 KASSERT(regs->r_access >= RTW_ACCESS_NONE && 373 regs->r_access <= RTW_ACCESS_ANAPARM); 374 375 if (naccess == regs->r_access) 376 return; 377 378 switch (naccess) { 379 case RTW_ACCESS_NONE: 380 switch (regs->r_access) { 381 case RTW_ACCESS_ANAPARM: 382 rtw_anaparm_enable(regs, 0); 383 /*FALLTHROUGH*/ 384 case RTW_ACCESS_CONFIG: 385 rtw_config0123_enable(regs, 0); 386 /*FALLTHROUGH*/ 387 case RTW_ACCESS_NONE: 388 break; 389 } 390 break; 391 case RTW_ACCESS_CONFIG: 392 switch (regs->r_access) { 393 case RTW_ACCESS_NONE: 394 rtw_config0123_enable(regs, 1); 395 /*FALLTHROUGH*/ 396 case RTW_ACCESS_CONFIG: 397 break; 398 case RTW_ACCESS_ANAPARM: 399 rtw_anaparm_enable(regs, 0); 400 break; 401 } 402 break; 403 case RTW_ACCESS_ANAPARM: 404 switch (regs->r_access) { 405 case RTW_ACCESS_NONE: 406 rtw_config0123_enable(regs, 1); 407 /*FALLTHROUGH*/ 408 case RTW_ACCESS_CONFIG: 409 rtw_anaparm_enable(regs, 1); 410 /*FALLTHROUGH*/ 411 case RTW_ACCESS_ANAPARM: 412 break; 413 } 414 break; 415 } 416 } 417 418 void 419 rtw_set_access(struct rtw_regs *regs, enum rtw_access access) 420 { 421 rtw_set_access1(regs, access); 422 RTW_DPRINTF(RTW_DEBUG_ACCESS, 423 ("%s: access %s -> %s\n", __func__, 424 rtw_access_string(regs->r_access), 425 rtw_access_string(access))); 426 regs->r_access = access; 427 } 428 429 /* 430 * Enable registers, switch register banks. 431 */ 432 void 433 rtw_config0123_enable(struct rtw_regs *regs, int enable) 434 { 435 uint8_t ecr; 436 ecr = RTW_READ8(regs, RTW_9346CR); 437 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK); 438 if (enable) 439 ecr |= RTW_9346CR_EEM_CONFIG; 440 else { 441 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3)); 442 ecr |= RTW_9346CR_EEM_NORMAL; 443 } 444 RTW_WRITE8(regs, RTW_9346CR, ecr); 445 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR); 446 } 447 448 /* requires rtw_config0123_enable(, 1) */ 449 void 450 rtw_anaparm_enable(struct rtw_regs *regs, int enable) 451 { 452 uint8_t cfg3; 453 454 cfg3 = RTW_READ8(regs, RTW_CONFIG3); 455 cfg3 |= RTW_CONFIG3_CLKRUNEN; 456 if (enable) 457 cfg3 |= RTW_CONFIG3_PARMEN; 458 else 459 cfg3 &= ~RTW_CONFIG3_PARMEN; 460 RTW_WRITE8(regs, RTW_CONFIG3, cfg3); 461 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3); 462 } 463 464 /* requires rtw_anaparm_enable(, 1) */ 465 void 466 rtw_txdac_enable(struct rtw_softc *sc, int enable) 467 { 468 uint32_t anaparm; 469 struct rtw_regs *regs = &sc->sc_regs; 470 471 anaparm = RTW_READ(regs, RTW_ANAPARM); 472 if (enable) 473 anaparm &= ~RTW_ANAPARM_TXDACOFF; 474 else 475 anaparm |= RTW_ANAPARM_TXDACOFF; 476 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 477 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 478 } 479 480 static __inline int 481 rtw_chip_reset1(struct rtw_regs *regs, const char *dvname) 482 { 483 uint8_t cr; 484 int i; 485 486 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST); 487 488 RTW_WBR(regs, RTW_CR, RTW_CR); 489 490 for (i = 0; i < 1000; i++) { 491 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) { 492 RTW_DPRINTF(RTW_DEBUG_RESET, 493 ("%s: reset in %dus\n", dvname, i)); 494 return 0; 495 } 496 RTW_RBR(regs, RTW_CR, RTW_CR); 497 DELAY(10); /* 10us */ 498 } 499 500 printf("%s: reset failed\n", dvname); 501 return ETIMEDOUT; 502 } 503 504 static __inline int 505 rtw_chip_reset(struct rtw_regs *regs, const char *dvname) 506 { 507 uint32_t tcr; 508 509 /* from Linux driver */ 510 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 | 511 LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK); 512 513 RTW_WRITE(regs, RTW_TCR, tcr); 514 515 RTW_WBW(regs, RTW_CR, RTW_TCR); 516 517 return rtw_chip_reset1(regs, dvname); 518 } 519 520 static void 521 rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_wepkey *wk, int txkey) 522 { 523 uint8_t cfg0, scr; 524 int i, j, tx_key_len; 525 struct rtw_regs *regs; 526 union rtw_keys *rk; 527 528 regs = &sc->sc_regs; 529 rk = &sc->sc_keys; 530 531 (void)memset(rk->rk_keys, 0, sizeof(rk->rk_keys)); 532 533 scr = RTW_READ8(regs, RTW_SCR); 534 cfg0 = RTW_READ8(regs, RTW_CONFIG0); 535 scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON); 536 cfg0 &= ~(RTW_CONFIG0_WEP104 | RTW_CONFIG0_WEP40); 537 538 rtw_set_access(regs, RTW_ACCESS_CONFIG); 539 540 if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0) 541 goto out; 542 543 tx_key_len = wk[txkey].wk_len; 544 545 switch (tx_key_len) { 546 case 5: 547 scr |= RTW_SCR_TXSECON | RTW_SCR_RXSECON | RTW_SCR_KM_WEP40; 548 break; 549 case 13: 550 scr |= RTW_SCR_TXSECON | RTW_SCR_RXSECON | RTW_SCR_KM_WEP104; 551 break; 552 default: 553 goto out; 554 } 555 556 cfg0 |= RTW_CONFIG0_WEP104 | RTW_CONFIG0_WEP40; 557 558 for (i = j = 0; i < IEEE80211_WEP_NKID; i++) { 559 if (i == txkey) 560 sc->sc_txkey = j; 561 else if (wk[i].wk_len != tx_key_len) 562 continue; 563 (void)memcpy(rk->rk_keys[j++], wk[i].wk_key, wk[i].wk_len); 564 } 565 566 out: 567 bus_space_write_region_4(regs->r_bt, regs->r_bh, 568 RTW_DK0, rk->rk_words, 569 sizeof(rk->rk_words) / sizeof(rk->rk_words[0])); 570 571 bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0, 572 sizeof(rk->rk_words) / sizeof(rk->rk_words[0]), 573 BUS_SPACE_BARRIER_SYNC); 574 575 RTW_WRITE8(regs, RTW_CONFIG0, cfg0); 576 RTW_WBW(regs, RTW_CONFIG0, RTW_SCR); 577 RTW_WRITE8(regs, RTW_SCR, scr); 578 RTW_SYNC(regs, RTW_SCR, RTW_SCR); 579 rtw_set_access(regs, RTW_ACCESS_NONE); 580 } 581 582 static __inline int 583 rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname) 584 { 585 int i; 586 uint8_t ecr; 587 588 ecr = RTW_READ8(regs, RTW_9346CR); 589 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD; 590 RTW_WRITE8(regs, RTW_9346CR, ecr); 591 592 RTW_WBR(regs, RTW_9346CR, RTW_9346CR); 593 594 /* wait 2.5ms for completion */ 595 for (i = 0; i < 25; i++) { 596 ecr = RTW_READ8(regs, RTW_9346CR); 597 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) { 598 RTW_DPRINTF(RTW_DEBUG_RESET, 599 ("%s: recall EEPROM in %dus\n", dvname, i * 100)); 600 return 0; 601 } 602 RTW_RBR(regs, RTW_9346CR, RTW_9346CR); 603 DELAY(100); 604 } 605 printf("%s: recall EEPROM failed\n", dvname); 606 return ETIMEDOUT; 607 } 608 609 static __inline int 610 rtw_reset(struct rtw_softc *sc) 611 { 612 int rc; 613 uint8_t config1; 614 615 if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 616 return rc; 617 618 if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0) 619 ; 620 621 config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1); 622 RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN); 623 /* TBD turn off maximum power saving? */ 624 625 return 0; 626 } 627 628 static __inline int 629 rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 630 u_int ndescs) 631 { 632 int i, rc = 0; 633 for (i = 0; i < ndescs; i++) { 634 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES, 635 0, 0, &descs[i].ts_dmamap); 636 if (rc != 0) 637 break; 638 } 639 return rc; 640 } 641 642 static __inline int 643 rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 644 u_int ndescs) 645 { 646 int i, rc = 0; 647 for (i = 0; i < ndescs; i++) { 648 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0, 649 &descs[i].rs_dmamap); 650 if (rc != 0) 651 break; 652 } 653 return rc; 654 } 655 656 static __inline void 657 rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs, 658 u_int ndescs) 659 { 660 int i; 661 for (i = 0; i < ndescs; i++) { 662 if (descs[i].rs_dmamap != NULL) 663 bus_dmamap_destroy(dmat, descs[i].rs_dmamap); 664 } 665 } 666 667 static __inline void 668 rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs, 669 u_int ndescs) 670 { 671 int i; 672 for (i = 0; i < ndescs; i++) { 673 if (descs[i].ts_dmamap != NULL) 674 bus_dmamap_destroy(dmat, descs[i].ts_dmamap); 675 } 676 } 677 678 static __inline void 679 rtw_srom_free(struct rtw_srom *sr) 680 { 681 sr->sr_size = 0; 682 if (sr->sr_content == NULL) 683 return; 684 free(sr->sr_content, M_DEVBUF); 685 sr->sr_content = NULL; 686 } 687 688 static void 689 rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold, 690 enum rtw_rfchipid *rfchipid, uint32_t *rcr) 691 { 692 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV); 693 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT; 694 *rcr |= RTW_RCR_ENCS1; 695 *rfchipid = RTW_RFCHIPID_PHILIPS; 696 } 697 698 static int 699 rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold, 700 enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale, 701 const char *dvname) 702 { 703 int i; 704 const char *rfname, *paname; 705 char scratch[sizeof("unknown 0xXX")]; 706 uint16_t version; 707 uint8_t mac[IEEE80211_ADDR_LEN]; 708 709 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV); 710 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2); 711 712 version = RTW_SR_GET16(sr, RTW_SR_VERSION); 713 printf("%s: SROM version %d.%d", dvname, version >> 8, version & 0xff); 714 715 if (version <= 0x0101) { 716 printf(" is not understood, limping along with defaults\n"); 717 rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr); 718 return 0; 719 } 720 printf("\n"); 721 722 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 723 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i); 724 725 RTW_DPRINTF(RTW_DEBUG_ATTACH, 726 ("%s: EEPROM MAC %s\n", dvname, ether_sprintf(mac))); 727 728 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR); 729 730 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0) 731 *flags |= RTW_F_ANTDIV; 732 733 /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems 734 * to be reversed. 735 */ 736 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0) 737 *flags |= RTW_F_DIGPHY; 738 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0) 739 *flags |= RTW_F_DFLANTB; 740 741 *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM), 742 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1); 743 744 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID); 745 switch (*rfchipid) { 746 case RTW_RFCHIPID_GCT: /* this combo seen in the wild */ 747 rfname = "GCT GRF5101"; 748 paname = "Winspring WS9901"; 749 break; 750 case RTW_RFCHIPID_MAXIM: 751 rfname = "Maxim MAX2820"; /* guess */ 752 paname = "Maxim MAX2422"; /* guess */ 753 break; 754 case RTW_RFCHIPID_INTERSIL: 755 rfname = "Intersil HFA3873"; /* guess */ 756 paname = "Intersil <unknown>"; 757 break; 758 case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */ 759 rfname = "Philips SA2400A"; 760 paname = "Philips SA2411"; 761 break; 762 case RTW_RFCHIPID_RFMD: 763 /* this is the same front-end as an atw(4)! */ 764 rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */ 765 "LNA: RFMD RF2494, " /* mentioned in Realtek docs */ 766 "SYN: Silicon Labs Si4126"; /* inferred from 767 * reference driver 768 */ 769 paname = "RFMD RF2189"; /* mentioned in Realtek docs */ 770 break; 771 case RTW_RFCHIPID_RESERVED: 772 rfname = paname = "reserved"; 773 break; 774 default: 775 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid); 776 rfname = paname = scratch; 777 } 778 printf("%s: RF: %s, PA: %s\n", 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 /* Returns -1 on failure. */ 798 static int 799 rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr, 800 const char *dvname) 801 { 802 int rc; 803 struct seeprom_descriptor sd; 804 uint8_t ecr; 805 806 (void)memset(&sd, 0, sizeof(sd)); 807 808 ecr = RTW_READ8(regs, RTW_9346CR); 809 810 if ((flags & RTW_F_9356SROM) != 0) { 811 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname)); 812 sr->sr_size = 256; 813 sd.sd_chip = C56_66; 814 } else { 815 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname)); 816 sr->sr_size = 128; 817 sd.sd_chip = C46; 818 } 819 820 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK | 821 RTW_9346CR_EEM_MASK | RTW_9346CR_EECS); 822 ecr |= RTW_9346CR_EEM_PROGRAM; 823 824 RTW_WRITE8(regs, RTW_9346CR, ecr); 825 826 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT); 827 828 if (sr->sr_content == NULL) { 829 printf("%s: unable to allocate SROM buffer\n", dvname); 830 return ENOMEM; 831 } 832 833 (void)memset(sr->sr_content, 0, sr->sr_size); 834 835 /* RTL8180 has a single 8-bit register for controlling the 836 * 93cx6 SROM. There is no "ready" bit. The RTL8180 837 * input/output sense is the reverse of read_seeprom's. 838 */ 839 sd.sd_tag = regs->r_bt; 840 sd.sd_bsh = regs->r_bh; 841 sd.sd_regsize = 1; 842 sd.sd_control_offset = RTW_9346CR; 843 sd.sd_status_offset = RTW_9346CR; 844 sd.sd_dataout_offset = RTW_9346CR; 845 sd.sd_CK = RTW_9346CR_EESK; 846 sd.sd_CS = RTW_9346CR_EECS; 847 sd.sd_DI = RTW_9346CR_EEDO; 848 sd.sd_DO = RTW_9346CR_EEDI; 849 /* make read_seeprom enter EEPROM read/write mode */ 850 sd.sd_MS = ecr; 851 sd.sd_RDY = 0; 852 853 /* TBD bus barriers */ 854 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) { 855 printf("%s: could not read SROM\n", dvname); 856 free(sr->sr_content, M_DEVBUF); 857 sr->sr_content = NULL; 858 return -1; /* XXX */ 859 } 860 861 /* end EEPROM read/write mode */ 862 RTW_WRITE8(regs, RTW_9346CR, 863 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL); 864 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR); 865 866 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0) 867 return rc; 868 869 #ifdef RTW_DEBUG 870 { 871 int i; 872 RTW_DPRINTF(RTW_DEBUG_ATTACH, 873 ("\n%s: serial ROM:\n\t", dvname)); 874 for (i = 0; i < sr->sr_size/2; i++) { 875 if (((i % 8) == 0) && (i != 0)) 876 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t")); 877 RTW_DPRINTF(RTW_DEBUG_ATTACH, 878 (" %04x", sr->sr_content[i])); 879 } 880 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n")); 881 } 882 #endif /* RTW_DEBUG */ 883 return 0; 884 } 885 886 static void 887 rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid, 888 const char *dvname) 889 { 890 uint8_t cfg4; 891 const char *method; 892 893 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK; 894 895 switch (rfchipid) { 896 default: 897 cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK); 898 method = "fallback"; 899 break; 900 case RTW_RFCHIPID_INTERSIL: 901 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL; 902 method = "Intersil"; 903 break; 904 case RTW_RFCHIPID_PHILIPS: 905 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS; 906 method = "Philips"; 907 break; 908 case RTW_RFCHIPID_GCT: /* XXX a guess */ 909 case RTW_RFCHIPID_RFMD: 910 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD; 911 method = "RFMD"; 912 break; 913 } 914 915 RTW_WRITE8(regs, RTW_CONFIG4, cfg4); 916 917 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4); 918 919 RTW_DPRINTF(RTW_DEBUG_INIT, 920 ("%s: %s RF programming method, %#02x\n", dvname, method, 921 RTW_READ8(regs, RTW_CONFIG4))); 922 } 923 924 static __inline void 925 rtw_init_channels(enum rtw_locale locale, 926 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], 927 const char *dvname) 928 { 929 int i; 930 const char *name = NULL; 931 #define ADD_CHANNEL(_chans, _chan) do { \ 932 (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \ 933 (*_chans)[_chan].ic_freq = \ 934 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\ 935 } while (0) 936 937 switch (locale) { 938 case RTW_LOCALE_USA: /* 1-11 */ 939 name = "USA"; 940 for (i = 1; i <= 11; i++) 941 ADD_CHANNEL(chans, i); 942 break; 943 case RTW_LOCALE_JAPAN: /* 1-14 */ 944 name = "Japan"; 945 ADD_CHANNEL(chans, 14); 946 for (i = 1; i <= 14; i++) 947 ADD_CHANNEL(chans, i); 948 break; 949 case RTW_LOCALE_EUROPE: /* 1-13 */ 950 name = "Europe"; 951 for (i = 1; i <= 13; i++) 952 ADD_CHANNEL(chans, i); 953 break; 954 default: /* 10-11 allowed by most countries */ 955 name = "<unknown>"; 956 for (i = 10; i <= 11; i++) 957 ADD_CHANNEL(chans, i); 958 break; 959 } 960 printf("%s: Geographic Location %s\n", dvname, name); 961 #undef ADD_CHANNEL 962 } 963 964 static __inline void 965 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale, 966 const char *dvname) 967 { 968 uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0); 969 970 switch (cfg0 & RTW_CONFIG0_GL_MASK) { 971 case RTW_CONFIG0_GL_USA: 972 *locale = RTW_LOCALE_USA; 973 break; 974 case RTW_CONFIG0_GL_JAPAN: 975 *locale = RTW_LOCALE_JAPAN; 976 break; 977 case RTW_CONFIG0_GL_EUROPE: 978 *locale = RTW_LOCALE_EUROPE; 979 break; 980 default: 981 *locale = RTW_LOCALE_UNKNOWN; 982 break; 983 } 984 } 985 986 static __inline int 987 rtw_identify_sta(struct rtw_regs *regs, uint8_t (*addr)[IEEE80211_ADDR_LEN], 988 const char *dvname) 989 { 990 static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 992 }; 993 uint32_t idr0 = RTW_READ(regs, RTW_IDR0), 994 idr1 = RTW_READ(regs, RTW_IDR1); 995 996 (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0, 7)); 997 (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8, 15)); 998 (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23)); 999 (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31)); 1000 1001 (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0, 7)); 1002 (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15)); 1003 1004 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) { 1005 printf("%s: could not get mac address, attach failed\n", 1006 dvname); 1007 return ENXIO; 1008 } 1009 1010 printf("%s: 802.11 address %s\n", dvname, ether_sprintf(*addr)); 1011 1012 return 0; 1013 } 1014 1015 static uint8_t 1016 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic, 1017 struct ieee80211_channel *chan) 1018 { 1019 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1; 1020 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14, 1021 ("%s: channel %d out of range", __func__, 1022 idx - RTW_SR_TXPOWER1 + 1)); 1023 return RTW_SR_GET(sr, idx); 1024 } 1025 1026 static void 1027 rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb) 1028 { 1029 int pri; 1030 u_int ndesc[RTW_NTXPRI] = 1031 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI, RTW_NTXDESCBCN}; 1032 1033 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1034 tdb[pri].tdb_nfree = ndesc[pri]; 1035 tdb[pri].tdb_next = 0; 1036 } 1037 } 1038 1039 static int 1040 rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb) 1041 { 1042 int i; 1043 struct rtw_txsoft *ts; 1044 1045 SIMPLEQ_INIT(&tsb->tsb_dirtyq); 1046 SIMPLEQ_INIT(&tsb->tsb_freeq); 1047 for (i = 0; i < tsb->tsb_ndesc; i++) { 1048 ts = &tsb->tsb_desc[i]; 1049 ts->ts_mbuf = NULL; 1050 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1051 } 1052 return 0; 1053 } 1054 1055 static void 1056 rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb) 1057 { 1058 int pri; 1059 for (pri = 0; pri < RTW_NTXPRI; pri++) 1060 rtw_txsoft_blk_init(&tsb[pri]); 1061 } 1062 1063 static __inline void 1064 rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops) 1065 { 1066 KASSERT(nsync <= rdb->rdb_ndesc); 1067 /* sync to end of ring */ 1068 if (desc0 + nsync > rdb->rdb_ndesc) { 1069 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1070 offsetof(struct rtw_descs, hd_rx[desc0]), 1071 sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops); 1072 nsync -= (rdb->rdb_ndesc - desc0); 1073 desc0 = 0; 1074 } 1075 1076 KASSERT(desc0 < rdb->rdb_ndesc); 1077 KASSERT(nsync <= rdb->rdb_ndesc); 1078 KASSERT(desc0 + nsync <= rdb->rdb_ndesc); 1079 1080 /* sync what remains */ 1081 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1082 offsetof(struct rtw_descs, hd_rx[desc0]), 1083 sizeof(struct rtw_rxdesc) * nsync, ops); 1084 } 1085 1086 static void 1087 rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops) 1088 { 1089 /* sync to end of ring */ 1090 if (desc0 + nsync > tdb->tdb_ndesc) { 1091 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 1092 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 1093 sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0), 1094 ops); 1095 nsync -= (tdb->tdb_ndesc - desc0); 1096 desc0 = 0; 1097 } 1098 1099 /* sync what remains */ 1100 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap, 1101 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0, 1102 sizeof(struct rtw_txdesc) * nsync, ops); 1103 } 1104 1105 static void 1106 rtw_txdescs_sync_all(struct rtw_txdesc_blk *tdb) 1107 { 1108 int pri; 1109 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1110 rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc, 1111 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1112 } 1113 } 1114 1115 static void 1116 rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc) 1117 { 1118 int i; 1119 struct rtw_rxsoft *rs; 1120 1121 for (i = 0; i < RTW_RXQLEN; i++) { 1122 rs = &desc[i]; 1123 if (rs->rs_mbuf == NULL) 1124 continue; 1125 bus_dmamap_sync(dmat, rs->rs_dmamap, 0, 1126 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1127 bus_dmamap_unload(dmat, rs->rs_dmamap); 1128 m_freem(rs->rs_mbuf); 1129 rs->rs_mbuf = NULL; 1130 } 1131 } 1132 1133 static __inline int 1134 rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs) 1135 { 1136 int rc; 1137 struct mbuf *m; 1138 1139 MGETHDR(m, M_DONTWAIT, MT_DATA); 1140 if (m == NULL) 1141 return ENOBUFS; 1142 1143 MCLGET(m, M_DONTWAIT); 1144 if ((m->m_flags & M_EXT) == 0) { 1145 m_freem(m); 1146 return ENOBUFS; 1147 } 1148 1149 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; 1150 1151 if (rs->rs_mbuf != NULL) 1152 bus_dmamap_unload(dmat, rs->rs_dmamap); 1153 1154 rs->rs_mbuf = NULL; 1155 1156 rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT); 1157 if (rc != 0) { 1158 m_freem(m); 1159 return -1; 1160 } 1161 1162 rs->rs_mbuf = m; 1163 1164 return 0; 1165 } 1166 1167 static int 1168 rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc, 1169 int *ndesc, const char *dvname) 1170 { 1171 int i, rc = 0; 1172 struct rtw_rxsoft *rs; 1173 1174 for (i = 0; i < RTW_RXQLEN; i++) { 1175 rs = &desc[i]; 1176 /* we're in rtw_init, so there should be no mbufs allocated */ 1177 KASSERT(rs->rs_mbuf == NULL); 1178 #ifdef RTW_DEBUG 1179 if (i == rtw_rxbufs_limit) { 1180 printf("%s: TEST hit %d-buffer limit\n", dvname, i); 1181 rc = ENOBUFS; 1182 break; 1183 } 1184 #endif /* RTW_DEBUG */ 1185 if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) { 1186 printf("%s: rtw_rxsoft_alloc failed, %d buffers, " 1187 "rc %d\n", dvname, i, rc); 1188 break; 1189 } 1190 } 1191 *ndesc = i; 1192 return rc; 1193 } 1194 1195 static __inline void 1196 rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs, 1197 int idx, int kick) 1198 { 1199 int is_last = (idx == rdb->rdb_ndesc - 1); 1200 uint32_t ctl, octl, obuf; 1201 struct rtw_rxdesc *rd = &rdb->rdb_desc[idx]; 1202 1203 obuf = rd->rd_buf; 1204 rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr); 1205 1206 ctl = LSHIFT(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) | 1207 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS; 1208 1209 if (is_last) 1210 ctl |= RTW_RXCTL_EOR; 1211 1212 octl = rd->rd_ctl; 1213 rd->rd_ctl = htole32(ctl); 1214 1215 RTW_DPRINTF( 1216 kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK) 1217 : RTW_DEBUG_RECV_DESC, 1218 ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd, 1219 le32toh(obuf), le32toh(rd->rd_buf), le32toh(octl), 1220 le32toh(rd->rd_ctl))); 1221 1222 /* sync the mbuf */ 1223 bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0, 1224 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1225 1226 /* sync the descriptor */ 1227 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap, 1228 RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc), 1229 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1230 } 1231 1232 static void 1233 rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, int kick) 1234 { 1235 int i; 1236 struct rtw_rxdesc *rd; 1237 struct rtw_rxsoft *rs; 1238 1239 for (i = 0; i < rdb->rdb_ndesc; i++) { 1240 rd = &rdb->rdb_desc[i]; 1241 rs = &ctl[i]; 1242 rtw_rxdesc_init(rdb, rs, i, kick); 1243 } 1244 rdb->rdb_next = 0; 1245 } 1246 1247 static void 1248 rtw_io_enable(struct rtw_regs *regs, uint8_t flags, int enable) 1249 { 1250 uint8_t cr; 1251 1252 RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__, 1253 enable ? "enable" : "disable", flags)); 1254 1255 cr = RTW_READ8(regs, RTW_CR); 1256 1257 /* XXX reference source does not enable MULRW */ 1258 #if 0 1259 /* enable PCI Read/Write Multiple */ 1260 cr |= RTW_CR_MULRW; 1261 #endif 1262 1263 RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */ 1264 if (enable) 1265 cr |= flags; 1266 else 1267 cr &= ~flags; 1268 RTW_WRITE8(regs, RTW_CR, cr); 1269 RTW_SYNC(regs, RTW_CR, RTW_CR); 1270 } 1271 1272 static void 1273 rtw_intr_rx(struct rtw_softc *sc, uint16_t isr) 1274 { 1275 #define IS_BEACON(__fc0) \ 1276 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\ 1277 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON)) 1278 1279 static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates: 1280 * hardware -> net80211 1281 */ 1282 u_int next, nproc = 0; 1283 int hwrate, len, rate, rssi, sq; 1284 uint32_t hrssi, hstat, htsfth, htsftl; 1285 struct rtw_rxdesc *rd; 1286 struct rtw_rxsoft *rs; 1287 struct rtw_rxdesc_blk *rdb; 1288 struct mbuf *m; 1289 1290 struct ieee80211_node *ni; 1291 struct ieee80211_frame *wh; 1292 1293 rdb = &sc->sc_rxdesc_blk; 1294 1295 KASSERT(rdb->rdb_next < rdb->rdb_ndesc); 1296 1297 for (next = rdb->rdb_next; ; next = (next + 1) % rdb->rdb_ndesc) { 1298 rtw_rxdescs_sync(rdb, next, 1, 1299 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1300 rd = &rdb->rdb_desc[next]; 1301 rs = &sc->sc_rxsoft[next]; 1302 1303 hstat = le32toh(rd->rd_stat); 1304 hrssi = le32toh(rd->rd_rssi); 1305 htsfth = le32toh(rd->rd_tsfth); 1306 htsftl = le32toh(rd->rd_tsftl); 1307 1308 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1309 ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n", 1310 __func__, next, hstat, hrssi, htsfth, htsftl)); 1311 1312 ++nproc; 1313 1314 /* still belongs to NIC */ 1315 if ((hstat & RTW_RXSTAT_OWN) != 0) { 1316 if (nproc > 1) 1317 break; 1318 1319 /* sometimes the NIC skips to the 0th descriptor */ 1320 rtw_rxdescs_sync(rdb, 0, 1, 1321 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1322 rd = &rdb->rdb_desc[0]; 1323 if ((rd->rd_stat & htole32(RTW_RXSTAT_OWN)) != 0) 1324 break; 1325 RTW_DPRINTF(RTW_DEBUG_BUGS, 1326 ("%s: NIC skipped to rxdesc[0]\n", 1327 sc->sc_dev.dv_xname)); 1328 next = 0; 1329 continue; 1330 } 1331 1332 if ((hstat & RTW_RXSTAT_IOERROR) != 0) { 1333 printf("%s: DMA error/FIFO overflow %08x, " 1334 "rx descriptor %d\n", sc->sc_dev.dv_xname, 1335 hstat & RTW_RXSTAT_IOERROR, next); 1336 sc->sc_if.if_ierrors++; 1337 goto next; 1338 } 1339 1340 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK); 1341 if (len < IEEE80211_MIN_LEN) { 1342 sc->sc_ic.ic_stats.is_rx_tooshort++; 1343 goto next; 1344 } 1345 1346 /* CRC is included with the packet; trim it off. */ 1347 len -= IEEE80211_CRC_LEN; 1348 1349 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK); 1350 if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) { 1351 printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname, 1352 MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK)); 1353 sc->sc_if.if_ierrors++; 1354 goto next; 1355 } 1356 rate = ratetbl[hwrate]; 1357 1358 #ifdef RTW_DEBUG 1359 #define PRINTSTAT(flag) do { \ 1360 if ((hstat & flag) != 0) { \ 1361 printf("%s" #flag, delim); \ 1362 delim = ","; \ 1363 } \ 1364 } while (0) 1365 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) { 1366 const char *delim = "<"; 1367 printf("%s: ", sc->sc_dev.dv_xname); 1368 if ((hstat & RTW_RXSTAT_DEBUG) != 0) { 1369 printf("status %08x", hstat); 1370 PRINTSTAT(RTW_RXSTAT_SPLCP); 1371 PRINTSTAT(RTW_RXSTAT_MAR); 1372 PRINTSTAT(RTW_RXSTAT_PAR); 1373 PRINTSTAT(RTW_RXSTAT_BAR); 1374 PRINTSTAT(RTW_RXSTAT_PWRMGT); 1375 PRINTSTAT(RTW_RXSTAT_CRC32); 1376 PRINTSTAT(RTW_RXSTAT_ICV); 1377 printf(">, "); 1378 } 1379 printf("rate %d.%d Mb/s, time %08x%08x\n", 1380 (rate * 5) / 10, (rate * 5) % 10, htsfth, htsftl); 1381 } 1382 #endif /* RTW_DEBUG */ 1383 1384 if ((hstat & RTW_RXSTAT_RES) != 0 && 1385 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) 1386 goto next; 1387 1388 /* if bad flags, skip descriptor */ 1389 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) { 1390 printf("%s: too many rx segments\n", 1391 sc->sc_dev.dv_xname); 1392 goto next; 1393 } 1394 1395 bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0, 1396 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); 1397 1398 m = rs->rs_mbuf; 1399 1400 /* if temporarily out of memory, re-use mbuf */ 1401 switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) { 1402 case 0: 1403 break; 1404 case ENOBUFS: 1405 printf("%s: rtw_rxsoft_alloc(, %d) failed, " 1406 "dropping packet\n", sc->sc_dev.dv_xname, next); 1407 goto next; 1408 default: 1409 /* XXX shorten rx ring, instead? */ 1410 panic("%s: could not load DMA map\n", 1411 sc->sc_dev.dv_xname); 1412 } 1413 1414 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS) 1415 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI); 1416 else { 1417 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI); 1418 /* TBD find out each front-end's LNA gain in the 1419 * front-end's units 1420 */ 1421 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0) 1422 rssi |= 0x80; 1423 } 1424 sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ); 1425 1426 /* Note well: now we cannot recycle the rs_mbuf unless 1427 * we restore its original length. 1428 */ 1429 m->m_pkthdr.rcvif = &sc->sc_if; 1430 m->m_pkthdr.len = m->m_len = len; 1431 1432 wh = mtod(m, struct ieee80211_frame *); 1433 1434 if (!IS_BEACON(wh->i_fc[0])) 1435 sc->sc_led_state.ls_event |= RTW_LED_S_RX; 1436 /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ 1437 ni = ieee80211_find_rxnode(&sc->sc_ic, wh); 1438 1439 sc->sc_tsfth = htsfth; 1440 1441 #ifdef RTW_DEBUG 1442 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 1443 (IFF_DEBUG|IFF_LINK2)) { 1444 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len, 1445 rate, rssi); 1446 } 1447 #endif /* RTW_DEBUG */ 1448 1449 #if NBPFILTER > 0 1450 if (sc->sc_radiobpf != NULL) { 1451 struct ieee80211com *ic = &sc->sc_ic; 1452 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap; 1453 1454 rr->rr_tsft = 1455 htole64(((uint64_t)htsfth << 32) | htsftl); 1456 1457 if ((hstat & RTW_RXSTAT_SPLCP) != 0) 1458 rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE; 1459 1460 rr->rr_flags = 0; 1461 rr->rr_rate = rate; 1462 rr->rr_chan_freq = 1463 htole16(ic->ic_bss->ni_chan->ic_freq); 1464 rr->rr_chan_flags = 1465 htole16(ic->ic_bss->ni_chan->ic_flags); 1466 rr->rr_antsignal = rssi; 1467 rr->rr_barker_lock = htole16(sq); 1468 1469 bpf_mtap2(sc->sc_radiobpf, (caddr_t)rr, 1470 sizeof(sc->sc_rxtapu), m); 1471 } 1472 #endif /* NPBFILTER > 0 */ 1473 1474 ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl); 1475 ieee80211_release_node(&sc->sc_ic, ni); 1476 next: 1477 rtw_rxdesc_init(rdb, rs, next, 0); 1478 } 1479 rdb->rdb_next = next; 1480 1481 KASSERT(rdb->rdb_next < rdb->rdb_ndesc); 1482 1483 return; 1484 #undef IS_BEACON 1485 } 1486 1487 static void 1488 rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1489 struct rtw_txsoft *ts) 1490 { 1491 struct mbuf *m; 1492 struct ieee80211_node *ni; 1493 1494 m = ts->ts_mbuf; 1495 ni = ts->ts_ni; 1496 KASSERT(m != NULL); 1497 KASSERT(ni != NULL); 1498 ts->ts_mbuf = NULL; 1499 ts->ts_ni = NULL; 1500 1501 bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize, 1502 BUS_DMASYNC_POSTWRITE); 1503 bus_dmamap_unload(dmat, ts->ts_dmamap); 1504 m_freem(m); 1505 ieee80211_release_node(ic, ni); 1506 } 1507 1508 static void 1509 rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic, 1510 struct rtw_txsoft_blk *tsb) 1511 { 1512 struct rtw_txsoft *ts; 1513 1514 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1515 rtw_txsoft_release(dmat, ic, ts); 1516 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1517 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1518 } 1519 } 1520 1521 static __inline void 1522 rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb, 1523 struct rtw_txsoft *ts, int ndesc) 1524 { 1525 uint32_t hstat; 1526 int data_retry, rts_retry; 1527 struct rtw_txdesc *tdn; 1528 const char *condstring; 1529 1530 rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts); 1531 1532 tdb->tdb_nfree += ndesc; 1533 1534 tdn = &tdb->tdb_desc[ts->ts_last]; 1535 1536 hstat = le32toh(tdn->td_stat); 1537 rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK); 1538 data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK); 1539 1540 sc->sc_if.if_collisions += rts_retry + data_retry; 1541 1542 if ((hstat & RTW_TXSTAT_TOK) != 0) 1543 condstring = "ok"; 1544 else { 1545 sc->sc_if.if_oerrors++; 1546 condstring = "error"; 1547 } 1548 1549 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 1550 ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n", 1551 sc->sc_dev.dv_xname, ts, ts->ts_first, ts->ts_last, 1552 condstring, rts_retry, data_retry)); 1553 } 1554 1555 /* Collect transmitted packets. */ 1556 static __inline void 1557 rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb, 1558 struct rtw_txdesc_blk *tdb) 1559 { 1560 int ndesc; 1561 struct rtw_txsoft *ts; 1562 1563 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) { 1564 ndesc = 1 + ts->ts_last - ts->ts_first; 1565 if (ts->ts_last < ts->ts_first) 1566 ndesc += tdb->tdb_ndesc; 1567 1568 KASSERT(ndesc > 0); 1569 1570 rtw_txdescs_sync(tdb, ts->ts_first, ndesc, 1571 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1572 1573 if ((tdb->tdb_desc[ts->ts_last].td_stat & 1574 htole32(RTW_TXSTAT_OWN)) != 0) 1575 break; 1576 1577 rtw_collect_txpkt(sc, tdb, ts, ndesc); 1578 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q); 1579 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q); 1580 sc->sc_if.if_flags &= ~IFF_OACTIVE; 1581 } 1582 if (ts == NULL) 1583 tsb->tsb_tx_timer = 0; 1584 } 1585 1586 static void 1587 rtw_intr_tx(struct rtw_softc *sc, uint16_t isr) 1588 { 1589 int pri; 1590 struct rtw_txsoft_blk *tsb; 1591 struct rtw_txdesc_blk *tdb; 1592 1593 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1594 tsb = &sc->sc_txsoft_blk[pri]; 1595 tdb = &sc->sc_txdesc_blk[pri]; 1596 1597 rtw_collect_txring(sc, tsb, tdb); 1598 1599 if ((isr & RTW_INTR_TX) != 0) 1600 rtw_start(&sc->sc_if); 1601 } 1602 1603 /* TBD */ 1604 return; 1605 } 1606 1607 static void 1608 rtw_intr_beacon(struct rtw_softc *sc, uint16_t isr) 1609 { 1610 /* TBD */ 1611 return; 1612 } 1613 1614 static void 1615 rtw_intr_atim(struct rtw_softc *sc) 1616 { 1617 /* TBD */ 1618 return; 1619 } 1620 1621 #ifdef RTW_DEBUG 1622 static void 1623 rtw_dump_rings(struct rtw_softc *sc) 1624 { 1625 struct rtw_txdesc_blk *tdb; 1626 struct rtw_rxdesc *rd; 1627 struct rtw_rxdesc_blk *rdb; 1628 int desc, pri; 1629 1630 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0) 1631 return; 1632 1633 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1634 tdb = &sc->sc_txdesc_blk[pri]; 1635 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri, 1636 tdb->tdb_ndesc, tdb->tdb_nfree); 1637 for (desc = 0; desc < tdb->tdb_ndesc; desc++) 1638 rtw_print_txdesc(sc, ".", NULL, tdb, desc); 1639 } 1640 1641 rdb = &sc->sc_rxdesc_blk; 1642 1643 for (desc = 0; desc < RTW_RXQLEN; desc++) { 1644 rd = &rdb->rdb_desc[desc]; 1645 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x " 1646 "rsvd1/tsfth %08x\n", __func__, 1647 (desc >= rdb->rdb_ndesc) ? "UNUSED " : "", 1648 le32toh(rd->rd_ctl), le32toh(rd->rd_rssi), 1649 le32toh(rd->rd_buf), le32toh(rd->rd_tsfth)); 1650 } 1651 } 1652 #endif /* RTW_DEBUG */ 1653 1654 static void 1655 rtw_hwring_setup(struct rtw_softc *sc) 1656 { 1657 struct rtw_regs *regs = &sc->sc_regs; 1658 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx)); 1659 RTW_WRITE(regs, RTW_TLPDA, RTW_RING_BASE(sc, hd_txlo)); 1660 RTW_WRITE(regs, RTW_TNPDA, RTW_RING_BASE(sc, hd_txmd)); 1661 RTW_WRITE(regs, RTW_THPDA, RTW_RING_BASE(sc, hd_txhi)); 1662 RTW_WRITE(regs, RTW_TBDA, RTW_RING_BASE(sc, hd_bcn)); 1663 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR); 1664 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1665 ("%s: reg[TLPDA] <- %" PRIxPTR "\n", __func__, 1666 (uintptr_t)RTW_RING_BASE(sc, hd_txlo))); 1667 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1668 ("%s: reg[TNPDA] <- %" PRIxPTR "\n", __func__, 1669 (uintptr_t)RTW_RING_BASE(sc, hd_txmd))); 1670 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1671 ("%s: reg[THPDA] <- %" PRIxPTR "\n", __func__, 1672 (uintptr_t)RTW_RING_BASE(sc, hd_txhi))); 1673 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC, 1674 ("%s: reg[TBDA] <- %" PRIxPTR "\n", __func__, 1675 (uintptr_t)RTW_RING_BASE(sc, hd_bcn))); 1676 RTW_DPRINTF(RTW_DEBUG_RECV_DESC, 1677 ("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__, 1678 (uintptr_t)RTW_RING_BASE(sc, hd_rx))); 1679 } 1680 1681 static int 1682 rtw_swring_setup(struct rtw_softc *sc) 1683 { 1684 int rc; 1685 struct rtw_rxdesc_blk *rdb; 1686 1687 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]); 1688 1689 rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]); 1690 1691 rdb = &sc->sc_rxdesc_blk; 1692 if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, &rdb->rdb_ndesc, 1693 sc->sc_dev.dv_xname)) != 0 && rdb->rdb_ndesc == 0) { 1694 printf("%s: could not allocate rx buffers\n", 1695 sc->sc_dev.dv_xname); 1696 return rc; 1697 } 1698 1699 rdb = &sc->sc_rxdesc_blk; 1700 rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc, 1701 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1702 rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1); 1703 1704 rtw_txdescs_sync_all(&sc->sc_txdesc_blk[0]); 1705 return 0; 1706 } 1707 1708 static void 1709 rtw_txdesc_blk_reset(struct rtw_txdesc_blk *tdb) 1710 { 1711 int i; 1712 1713 (void)memset(tdb->tdb_desc, 0, 1714 sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 1715 for (i = 0; i < tdb->tdb_ndesc; i++) 1716 tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i)); 1717 tdb->tdb_nfree = tdb->tdb_ndesc; 1718 tdb->tdb_next = 0; 1719 } 1720 1721 static void 1722 rtw_txdescs_reset(struct rtw_softc *sc) 1723 { 1724 int pri; 1725 struct rtw_txdesc_blk *tdb; 1726 1727 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1728 tdb = &sc->sc_txdesc_blk[pri]; 1729 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic, 1730 &sc->sc_txsoft_blk[pri]); 1731 rtw_txdesc_blk_reset(tdb); 1732 rtw_txdescs_sync(tdb, 0, tdb->tdb_ndesc, 1733 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 1734 } 1735 } 1736 1737 static void 1738 rtw_rxdescs_reset(struct rtw_softc *sc) 1739 { 1740 rtw_rxdesc_init_all(&sc->sc_rxdesc_blk, &sc->sc_rxsoft[0], 1); 1741 } 1742 1743 static void 1744 rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr) 1745 { 1746 struct rtw_regs *regs = &sc->sc_regs; 1747 1748 if ((isr & RTW_INTR_TXFOVW) != 0) 1749 printf("%s: tx fifo overflow\n", sc->sc_dev.dv_xname); 1750 1751 if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) == 0) 1752 return; 1753 1754 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv\n", 1755 sc->sc_dev.dv_xname)); 1756 1757 #ifdef RTW_DEBUG 1758 rtw_dump_rings(sc); 1759 #endif /* RTW_DEBUG */ 1760 1761 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 0); 1762 1763 /* Collect rx'd packets. Refresh rx buffers. */ 1764 rtw_intr_rx(sc, 0); 1765 /* Collect tx'd packets. */ 1766 rtw_intr_tx(sc, 0); 1767 1768 RTW_WRITE16(regs, RTW_IMR, 0); 1769 RTW_SYNC(regs, RTW_IMR, RTW_IMR); 1770 1771 rtw_chip_reset1(regs, sc->sc_dev.dv_xname); 1772 1773 rtw_rxdescs_reset(sc); 1774 rtw_txdescs_reset(sc); 1775 1776 rtw_hwring_setup(sc); 1777 1778 #ifdef RTW_DEBUG 1779 rtw_dump_rings(sc); 1780 #endif /* RTW_DEBUG */ 1781 1782 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 1783 RTW_SYNC(regs, RTW_IMR, RTW_IMR); 1784 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1); 1785 } 1786 1787 static __inline void 1788 rtw_suspend_ticks(struct rtw_softc *sc) 1789 { 1790 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 1791 ("%s: suspending ticks\n", sc->sc_dev.dv_xname)); 1792 sc->sc_do_tick = 0; 1793 } 1794 1795 static __inline void 1796 rtw_resume_ticks(struct rtw_softc *sc) 1797 { 1798 uint32_t tsftrl0, tsftrl1, next_tick; 1799 1800 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1801 1802 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL); 1803 next_tick = tsftrl1 + 1000000; 1804 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick); 1805 1806 sc->sc_do_tick = 1; 1807 1808 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, 1809 ("%s: resume ticks delta %#08x now %#08x next %#08x\n", 1810 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick)); 1811 } 1812 1813 static void 1814 rtw_intr_timeout(struct rtw_softc *sc) 1815 { 1816 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname)); 1817 if (sc->sc_do_tick) 1818 rtw_resume_ticks(sc); 1819 return; 1820 } 1821 1822 int 1823 rtw_intr(void *arg) 1824 { 1825 int i; 1826 struct rtw_softc *sc = arg; 1827 struct rtw_regs *regs = &sc->sc_regs; 1828 uint16_t isr; 1829 1830 /* 1831 * If the interface isn't running, the interrupt couldn't 1832 * possibly have come from us. 1833 */ 1834 if ((sc->sc_flags & RTW_F_ENABLED) == 0 || 1835 (sc->sc_if.if_flags & IFF_RUNNING) == 0 || 1836 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) { 1837 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n", sc->sc_dev.dv_xname)); 1838 return (0); 1839 } 1840 1841 for (i = 0; i < 10; i++) { 1842 isr = RTW_READ16(regs, RTW_ISR); 1843 1844 RTW_WRITE16(regs, RTW_ISR, isr); 1845 RTW_WBR(regs, RTW_ISR, RTW_ISR); 1846 1847 if (sc->sc_intr_ack != NULL) 1848 (*sc->sc_intr_ack)(regs); 1849 1850 if (isr == 0) 1851 break; 1852 1853 #ifdef RTW_DEBUG 1854 #define PRINTINTR(flag) do { \ 1855 if ((isr & flag) != 0) { \ 1856 printf("%s" #flag, delim); \ 1857 delim = ","; \ 1858 } \ 1859 } while (0) 1860 1861 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) { 1862 const char *delim = "<"; 1863 1864 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr); 1865 1866 PRINTINTR(RTW_INTR_TXFOVW); 1867 PRINTINTR(RTW_INTR_TIMEOUT); 1868 PRINTINTR(RTW_INTR_BCNINT); 1869 PRINTINTR(RTW_INTR_ATIMINT); 1870 PRINTINTR(RTW_INTR_TBDER); 1871 PRINTINTR(RTW_INTR_TBDOK); 1872 PRINTINTR(RTW_INTR_THPDER); 1873 PRINTINTR(RTW_INTR_THPDOK); 1874 PRINTINTR(RTW_INTR_TNPDER); 1875 PRINTINTR(RTW_INTR_TNPDOK); 1876 PRINTINTR(RTW_INTR_RXFOVW); 1877 PRINTINTR(RTW_INTR_RDU); 1878 PRINTINTR(RTW_INTR_TLPDER); 1879 PRINTINTR(RTW_INTR_TLPDOK); 1880 PRINTINTR(RTW_INTR_RER); 1881 PRINTINTR(RTW_INTR_ROK); 1882 1883 printf(">\n"); 1884 } 1885 #undef PRINTINTR 1886 #endif /* RTW_DEBUG */ 1887 1888 if ((isr & RTW_INTR_RX) != 0) 1889 rtw_intr_rx(sc, isr & RTW_INTR_RX); 1890 if ((isr & RTW_INTR_TX) != 0) 1891 rtw_intr_tx(sc, isr & RTW_INTR_TX); 1892 if ((isr & RTW_INTR_BEACON) != 0) 1893 rtw_intr_beacon(sc, isr & RTW_INTR_BEACON); 1894 if ((isr & RTW_INTR_ATIMINT) != 0) 1895 rtw_intr_atim(sc); 1896 if ((isr & RTW_INTR_IOERROR) != 0) 1897 rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR); 1898 if ((isr & RTW_INTR_TIMEOUT) != 0) 1899 rtw_intr_timeout(sc); 1900 } 1901 1902 return 1; 1903 } 1904 1905 /* Must be called at splnet. */ 1906 static void 1907 rtw_stop(struct ifnet *ifp, int disable) 1908 { 1909 int pri; 1910 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 1911 struct ieee80211com *ic = &sc->sc_ic; 1912 struct rtw_regs *regs = &sc->sc_regs; 1913 1914 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 1915 return; 1916 1917 rtw_suspend_ticks(sc); 1918 1919 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1920 1921 if ((sc->sc_flags & RTW_F_INVALID) == 0) { 1922 /* Disable interrupts. */ 1923 RTW_WRITE16(regs, RTW_IMR, 0); 1924 1925 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR); 1926 1927 /* Stop the transmit and receive processes. First stop DMA, 1928 * then disable receiver and transmitter. 1929 */ 1930 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL); 1931 1932 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR); 1933 1934 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0); 1935 } 1936 1937 for (pri = 0; pri < RTW_NTXPRI; pri++) { 1938 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic, 1939 &sc->sc_txsoft_blk[pri]); 1940 } 1941 1942 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]); 1943 1944 if (disable) 1945 rtw_disable(sc); 1946 1947 /* Mark the interface as not running. Cancel the watchdog timer. */ 1948 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1949 ifp->if_timer = 0; 1950 1951 return; 1952 } 1953 1954 const char * 1955 rtw_pwrstate_string(enum rtw_pwrstate power) 1956 { 1957 switch (power) { 1958 case RTW_ON: 1959 return "on"; 1960 case RTW_SLEEP: 1961 return "sleep"; 1962 case RTW_OFF: 1963 return "off"; 1964 default: 1965 return "unknown"; 1966 } 1967 } 1968 1969 /* XXX For Maxim, I am using the RFMD settings gleaned from the 1970 * reference driver, plus a magic Maxim "ON" value that comes from 1971 * the Realtek document "Windows PG for Rtl8180." 1972 */ 1973 static void 1974 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 1975 int before_rf, int digphy) 1976 { 1977 uint32_t anaparm; 1978 1979 anaparm = RTW_READ(regs, RTW_ANAPARM); 1980 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 1981 1982 switch (power) { 1983 case RTW_OFF: 1984 if (before_rf) 1985 return; 1986 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF; 1987 anaparm |= RTW_ANAPARM_TXDACOFF; 1988 break; 1989 case RTW_SLEEP: 1990 if (!before_rf) 1991 return; 1992 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP; 1993 anaparm |= RTW_ANAPARM_TXDACOFF; 1994 break; 1995 case RTW_ON: 1996 if (!before_rf) 1997 return; 1998 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON; 1999 break; 2000 } 2001 RTW_DPRINTF(RTW_DEBUG_PWR, 2002 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2003 __func__, rtw_pwrstate_string(power), 2004 (before_rf) ? "before" : "after", anaparm)); 2005 2006 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2007 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2008 } 2009 2010 /* XXX I am using the RFMD settings gleaned from the reference 2011 * driver. They agree 2012 */ 2013 static void 2014 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2015 int before_rf, int digphy) 2016 { 2017 uint32_t anaparm; 2018 2019 anaparm = RTW_READ(regs, RTW_ANAPARM); 2020 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2021 2022 switch (power) { 2023 case RTW_OFF: 2024 if (before_rf) 2025 return; 2026 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF; 2027 anaparm |= RTW_ANAPARM_TXDACOFF; 2028 break; 2029 case RTW_SLEEP: 2030 if (!before_rf) 2031 return; 2032 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP; 2033 anaparm |= RTW_ANAPARM_TXDACOFF; 2034 break; 2035 case RTW_ON: 2036 if (!before_rf) 2037 return; 2038 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON; 2039 break; 2040 } 2041 RTW_DPRINTF(RTW_DEBUG_PWR, 2042 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2043 __func__, rtw_pwrstate_string(power), 2044 (before_rf) ? "before" : "after", anaparm)); 2045 2046 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2047 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2048 } 2049 2050 static void 2051 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power, 2052 int before_rf, int digphy) 2053 { 2054 uint32_t anaparm; 2055 2056 anaparm = RTW_READ(regs, RTW_ANAPARM); 2057 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF); 2058 2059 switch (power) { 2060 case RTW_OFF: 2061 if (before_rf) 2062 return; 2063 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF; 2064 anaparm |= RTW_ANAPARM_TXDACOFF; 2065 break; 2066 case RTW_SLEEP: 2067 if (!before_rf) 2068 return; 2069 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP; 2070 anaparm |= RTW_ANAPARM_TXDACOFF; 2071 break; 2072 case RTW_ON: 2073 if (!before_rf) 2074 return; 2075 if (digphy) { 2076 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON; 2077 /* XXX guess */ 2078 anaparm |= RTW_ANAPARM_TXDACOFF; 2079 } else 2080 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON; 2081 break; 2082 } 2083 RTW_DPRINTF(RTW_DEBUG_PWR, 2084 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n", 2085 __func__, rtw_pwrstate_string(power), 2086 (before_rf) ? "before" : "after", anaparm)); 2087 2088 RTW_WRITE(regs, RTW_ANAPARM, anaparm); 2089 RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM); 2090 } 2091 2092 static void 2093 rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf, 2094 int digphy) 2095 { 2096 struct rtw_regs *regs = &sc->sc_regs; 2097 2098 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2099 2100 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy); 2101 2102 rtw_set_access(regs, RTW_ACCESS_NONE); 2103 2104 return; 2105 } 2106 2107 static int 2108 rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power) 2109 { 2110 int rc; 2111 2112 RTW_DPRINTF(RTW_DEBUG_PWR, 2113 ("%s: %s->%s\n", __func__, 2114 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power))); 2115 2116 if (sc->sc_pwrstate == power) 2117 return 0; 2118 2119 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY); 2120 rc = rtw_rf_pwrstate(sc->sc_rf, power); 2121 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY); 2122 2123 switch (power) { 2124 case RTW_ON: 2125 /* TBD set LEDs */ 2126 break; 2127 case RTW_SLEEP: 2128 /* TBD */ 2129 break; 2130 case RTW_OFF: 2131 /* TBD */ 2132 break; 2133 } 2134 if (rc == 0) 2135 sc->sc_pwrstate = power; 2136 else 2137 sc->sc_pwrstate = RTW_OFF; 2138 return rc; 2139 } 2140 2141 static int 2142 rtw_tune(struct rtw_softc *sc) 2143 { 2144 struct ieee80211com *ic = &sc->sc_ic; 2145 u_int chan; 2146 int rc; 2147 int antdiv = sc->sc_flags & RTW_F_ANTDIV, 2148 dflantb = sc->sc_flags & RTW_F_DFLANTB; 2149 2150 KASSERT(ic->ic_bss->ni_chan != NULL); 2151 2152 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan); 2153 if (chan == IEEE80211_CHAN_ANY) 2154 panic("%s: chan == IEEE80211_CHAN_ANY\n", __func__); 2155 2156 if (chan == sc->sc_cur_chan) { 2157 RTW_DPRINTF(RTW_DEBUG_TUNE, 2158 ("%s: already tuned chan #%d\n", __func__, chan)); 2159 return 0; 2160 } 2161 2162 rtw_suspend_ticks(sc); 2163 2164 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0); 2165 2166 /* TBD wait for Tx to complete */ 2167 2168 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0); 2169 2170 if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf, 2171 rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_bss->ni_chan), 2172 sc->sc_csthr, ic->ic_bss->ni_chan->ic_freq, antdiv, 2173 dflantb, RTW_ON)) != 0) { 2174 /* XXX condition on powersaving */ 2175 printf("%s: phy init failed\n", sc->sc_dev.dv_xname); 2176 } 2177 2178 sc->sc_cur_chan = chan; 2179 2180 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1); 2181 2182 rtw_resume_ticks(sc); 2183 2184 return rc; 2185 } 2186 2187 void 2188 rtw_disable(struct rtw_softc *sc) 2189 { 2190 int rc; 2191 2192 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 2193 return; 2194 2195 /* turn off PHY */ 2196 if ((sc->sc_flags & RTW_F_INVALID) == 0 && 2197 (rc = rtw_pwrstate(sc, RTW_OFF)) != 0) { 2198 printf("%s: failed to turn off PHY (%d)\n", 2199 sc->sc_dev.dv_xname, rc); 2200 } 2201 2202 if (sc->sc_disable != NULL) 2203 (*sc->sc_disable)(sc); 2204 2205 sc->sc_flags &= ~RTW_F_ENABLED; 2206 } 2207 2208 int 2209 rtw_enable(struct rtw_softc *sc) 2210 { 2211 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 2212 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) { 2213 printf("%s: device enable failed\n", 2214 sc->sc_dev.dv_xname); 2215 return (EIO); 2216 } 2217 sc->sc_flags |= RTW_F_ENABLED; 2218 } 2219 return (0); 2220 } 2221 2222 static void 2223 rtw_transmit_config(struct rtw_regs *regs) 2224 { 2225 uint32_t tcr; 2226 2227 tcr = RTW_READ(regs, RTW_TCR); 2228 2229 tcr |= RTW_TCR_CWMIN; 2230 tcr &= ~RTW_TCR_MXDMA_MASK; 2231 tcr |= RTW_TCR_MXDMA_256; 2232 tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */ 2233 tcr &= ~RTW_TCR_LBK_MASK; 2234 tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */ 2235 2236 /* set short/long retry limits */ 2237 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK); 2238 tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK); 2239 2240 tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */ 2241 2242 RTW_WRITE(regs, RTW_TCR, tcr); 2243 RTW_SYNC(regs, RTW_TCR, RTW_TCR); 2244 } 2245 2246 static __inline void 2247 rtw_enable_interrupts(struct rtw_softc *sc) 2248 { 2249 struct rtw_regs *regs = &sc->sc_regs; 2250 2251 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT; 2252 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT; 2253 2254 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten); 2255 RTW_WBW(regs, RTW_IMR, RTW_ISR); 2256 RTW_WRITE16(regs, RTW_ISR, 0xffff); 2257 RTW_SYNC(regs, RTW_IMR, RTW_ISR); 2258 2259 /* XXX necessary? */ 2260 if (sc->sc_intr_ack != NULL) 2261 (*sc->sc_intr_ack)(regs); 2262 } 2263 2264 static void 2265 rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode) 2266 { 2267 uint8_t msr; 2268 2269 /* I'm guessing that MSR is protected as CONFIG[0123] are. */ 2270 rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG); 2271 2272 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK; 2273 2274 switch (opmode) { 2275 case IEEE80211_M_AHDEMO: 2276 case IEEE80211_M_IBSS: 2277 msr |= RTW_MSR_NETYPE_ADHOC_OK; 2278 break; 2279 case IEEE80211_M_HOSTAP: 2280 msr |= RTW_MSR_NETYPE_AP_OK; 2281 break; 2282 case IEEE80211_M_MONITOR: 2283 /* XXX */ 2284 msr |= RTW_MSR_NETYPE_NOLINK; 2285 break; 2286 case IEEE80211_M_STA: 2287 msr |= RTW_MSR_NETYPE_INFRA_OK; 2288 break; 2289 } 2290 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr); 2291 2292 rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE); 2293 } 2294 2295 #define rtw_calchash(addr) \ 2296 (ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26) 2297 2298 static void 2299 rtw_pktfilt_load(struct rtw_softc *sc) 2300 { 2301 struct rtw_regs *regs = &sc->sc_regs; 2302 struct ieee80211com *ic = &sc->sc_ic; 2303 struct ethercom *ec = &ic->ic_ec; 2304 struct ifnet *ifp = &sc->sc_ic.ic_if; 2305 int hash; 2306 uint32_t hashes[2] = { 0, 0 }; 2307 struct ether_multi *enm; 2308 struct ether_multistep step; 2309 2310 /* XXX might be necessary to stop Rx/Tx engines while setting filters */ 2311 2312 sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK; 2313 sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK); 2314 2315 sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT; 2316 /* MAC auto-reset PHY (huh?) */ 2317 sc->sc_rcr |= RTW_RCR_ENMARP; 2318 /* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */ 2319 sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE; 2320 2321 switch (ic->ic_opmode) { 2322 case IEEE80211_M_MONITOR: 2323 sc->sc_rcr |= RTW_RCR_MONITOR; 2324 break; 2325 case IEEE80211_M_AHDEMO: 2326 case IEEE80211_M_IBSS: 2327 /* receive broadcasts in our BSS */ 2328 sc->sc_rcr |= RTW_RCR_ADD3; 2329 break; 2330 default: 2331 break; 2332 } 2333 2334 ifp->if_flags &= ~IFF_ALLMULTI; 2335 2336 /* XXX accept all broadcast if scanning */ 2337 if ((ifp->if_flags & IFF_BROADCAST) != 0) 2338 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2339 2340 if (ifp->if_flags & IFF_PROMISC) { 2341 sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */ 2342 allmulti: 2343 ifp->if_flags |= IFF_ALLMULTI; 2344 goto setit; 2345 } 2346 2347 /* 2348 * Program the 64-bit multicast hash filter. 2349 */ 2350 ETHER_FIRST_MULTI(step, ec, enm); 2351 while (enm != NULL) { 2352 /* XXX */ 2353 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 2354 ETHER_ADDR_LEN) != 0) 2355 goto allmulti; 2356 2357 hash = rtw_calchash(enm->enm_addrlo); 2358 hashes[hash >> 5] |= (1 << (hash & 0x1f)); 2359 sc->sc_rcr |= RTW_RCR_AM; 2360 ETHER_NEXT_MULTI(step, enm); 2361 } 2362 2363 /* all bits set => hash is useless */ 2364 if (~(hashes[0] & hashes[1]) == 0) 2365 goto allmulti; 2366 2367 setit: 2368 if (ifp->if_flags & IFF_ALLMULTI) { 2369 sc->sc_rcr |= RTW_RCR_AM; /* accept all multicast */ 2370 hashes[0] = hashes[1] = 0xffffffff; 2371 } 2372 2373 RTW_WRITE(regs, RTW_MAR0, hashes[0]); 2374 RTW_WRITE(regs, RTW_MAR1, hashes[1]); 2375 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr); 2376 RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */ 2377 2378 DPRINTF(sc, RTW_DEBUG_PKTFILT, 2379 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n", 2380 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0), 2381 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR))); 2382 2383 return; 2384 } 2385 2386 #define IEEE80211_BEACON_TIMESTAMP_LEN 8 2387 #define IEEE80211_BEACON_BINTVL_LEN 2 2388 #define IEEE80211_BEACON_CAPINFO_LEN 2 2389 #define IEEE80211_TLV_SSID_LEN(__esslen) (2 + (__esslen)) 2390 #define IEEE80211_TLV_SUPRATES_LEN(__nrates) (2 + (__nrates)) 2391 #define IEEE80211_TLV_XSUPRATES_LEN(__nrates) (2 + (__nrates)) 2392 #define IEEE80211_TLV_DSPARMS_LEN 3 2393 #define IEEE80211_TLV_IBSSPARMS 4 2394 #define IEEE80211_TLV_MIN_TIM 6 2395 2396 #define IEEE80211_TLV_ALLRATES_LEN(__nrates) \ 2397 (((__nrates) > IEEE80211_RATE_SIZE) ? 4 + (__nrates) : 2 + (__nrates)) 2398 2399 /* TBD factor with ieee80211_getmbuf */ 2400 static struct mbuf * 2401 rtw_getmbuf(int flags, int type, u_int pktlen) 2402 { 2403 struct mbuf *m; 2404 2405 KASSERT2(pktlen <= MCLBYTES, ("802.11 packet too large: %u", pktlen)); 2406 MGETHDR(m, flags, type); 2407 if (m == NULL || pktlen <= MHLEN) 2408 return m; 2409 MCLGET(m, flags); 2410 if ((m->m_flags & M_EXT) != 0) 2411 return m; 2412 m_free(m); 2413 return NULL; 2414 } 2415 2416 /* TBD factor with ath_beacon_alloc */ 2417 static struct mbuf * 2418 rtw_beacon_alloc(struct rtw_softc *sc, struct ieee80211_node *ni) 2419 { 2420 struct ieee80211com *ic = &sc->sc_ic; 2421 struct ifnet *ifp = &ic->ic_if; 2422 struct ieee80211_frame *wh; 2423 struct mbuf *m; 2424 int pktlen; 2425 uint8_t *frm; 2426 uint16_t capinfo; 2427 struct ieee80211_rateset *rs; 2428 2429 /* 2430 * NB: the beacon data buffer must be 32-bit aligned; 2431 * we assume the mbuf routines will return us something 2432 * with this alignment (perhaps should assert). 2433 */ 2434 rs = &ni->ni_rates; 2435 pktlen = sizeof(struct ieee80211_frame) 2436 + IEEE80211_BEACON_TIMESTAMP_LEN 2437 + IEEE80211_BEACON_BINTVL_LEN 2438 + IEEE80211_BEACON_CAPINFO_LEN 2439 + IEEE80211_TLV_SSID_LEN(ni->ni_esslen) 2440 + IEEE80211_TLV_ALLRATES_LEN(rs->rs_nrates) 2441 + IEEE80211_TLV_DSPARMS_LEN 2442 + MAX(IEEE80211_TLV_IBSSPARMS, IEEE80211_TLV_MIN_TIM); 2443 2444 m = rtw_getmbuf(M_DONTWAIT, MT_DATA, pktlen); 2445 if (m == NULL) { 2446 RTW_DPRINTF(RTW_DEBUG_BEACON, 2447 ("%s: cannot get mbuf/cluster; size %u\n", 2448 __func__, pktlen)); 2449 #if 0 2450 sc->sc_stats.ast_be_nombuf++; 2451 #endif 2452 return NULL; 2453 } 2454 2455 wh = mtod(m, struct ieee80211_frame *); 2456 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 2457 IEEE80211_FC0_SUBTYPE_BEACON; 2458 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 2459 *(u_int16_t *)wh->i_dur = 0; 2460 memcpy(wh->i_addr1, ifp->if_broadcastaddr, IEEE80211_ADDR_LEN); 2461 memcpy(wh->i_addr2, ic->ic_myaddr, IEEE80211_ADDR_LEN); 2462 memcpy(wh->i_addr3, ni->ni_bssid, IEEE80211_ADDR_LEN); 2463 *(u_int16_t *)wh->i_seq = 0; 2464 2465 /* 2466 * beacon frame format 2467 * [8] time stamp 2468 * [2] beacon interval 2469 * [2] cabability information 2470 * [tlv] ssid 2471 * [tlv] supported rates 2472 * [tlv] parameter set (IBSS) 2473 * [tlv] extended supported rates 2474 */ 2475 frm = (u_int8_t *)&wh[1]; 2476 /* timestamp is set by hardware */ 2477 memset(frm, 0, IEEE80211_BEACON_TIMESTAMP_LEN); 2478 frm += IEEE80211_BEACON_TIMESTAMP_LEN; 2479 *(u_int16_t *)frm = htole16(ni->ni_intval); 2480 frm += IEEE80211_BEACON_BINTVL_LEN; 2481 if (ic->ic_opmode == IEEE80211_M_IBSS) 2482 capinfo = IEEE80211_CAPINFO_IBSS; 2483 else 2484 capinfo = IEEE80211_CAPINFO_ESS; 2485 if (ic->ic_flags & IEEE80211_F_PRIVACY) 2486 capinfo |= IEEE80211_CAPINFO_PRIVACY; 2487 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && 2488 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) 2489 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE; 2490 if (ic->ic_flags & IEEE80211_F_SHSLOT) 2491 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME; 2492 *(u_int16_t *)frm = htole16(capinfo); 2493 frm += IEEE80211_BEACON_CAPINFO_LEN; 2494 *frm++ = IEEE80211_ELEMID_SSID; 2495 *frm++ = ni->ni_esslen; 2496 memcpy(frm, ni->ni_essid, ni->ni_esslen); 2497 frm += ni->ni_esslen; 2498 frm = ieee80211_add_rates(frm, rs); 2499 *frm++ = IEEE80211_ELEMID_DSPARMS; 2500 *frm++ = 1; 2501 *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan); 2502 if (ic->ic_opmode == IEEE80211_M_IBSS) { 2503 *frm++ = IEEE80211_ELEMID_IBSSPARMS; 2504 *frm++ = 2; 2505 *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ 2506 } else { 2507 /* TODO: TIM */ 2508 *frm++ = IEEE80211_ELEMID_TIM; 2509 *frm++ = 4; /* length */ 2510 *frm++ = 0; /* DTIM count */ 2511 *frm++ = 1; /* DTIM period */ 2512 *frm++ = 0; /* bitmap control */ 2513 *frm++ = 0; /* Partial Virtual Bitmap (variable length) */ 2514 } 2515 frm = ieee80211_add_xrates(frm, rs); 2516 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); 2517 m->m_pkthdr.rcvif = (void *)ni; 2518 KASSERT2(m->m_pkthdr.len <= pktlen, 2519 ("beacon bigger than expected, len %u calculated %u", 2520 m->m_pkthdr.len, pktlen)); 2521 2522 RTW_DPRINTF(RTW_DEBUG_BEACON, 2523 ("%s: m %p len %u\n", __func__, m, m->m_len)); 2524 2525 return m; 2526 } 2527 2528 /* Must be called at splnet. */ 2529 static int 2530 rtw_init(struct ifnet *ifp) 2531 { 2532 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc; 2533 struct ieee80211com *ic = &sc->sc_ic; 2534 struct rtw_regs *regs = &sc->sc_regs; 2535 int rc = 0; 2536 2537 if ((rc = rtw_enable(sc)) != 0) 2538 goto out; 2539 2540 /* Cancel pending I/O and reset. */ 2541 rtw_stop(ifp, 0); 2542 2543 ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2544 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n", 2545 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), 2546 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags)); 2547 2548 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) 2549 goto out; 2550 2551 if ((rc = rtw_swring_setup(sc)) != 0) 2552 goto out; 2553 2554 rtw_transmit_config(regs); 2555 2556 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2557 2558 RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */ 2559 RTW_WBW(regs, RTW_MSR, RTW_BRSR); 2560 2561 /* long PLCP header, 1Mb/2Mb basic rate */ 2562 RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS); 2563 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR); 2564 2565 rtw_set_access(regs, RTW_ACCESS_ANAPARM); 2566 rtw_set_access(regs, RTW_ACCESS_NONE); 2567 2568 /* XXX from reference sources */ 2569 RTW_WRITE(regs, RTW_FEMR, 0xffff); 2570 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR); 2571 2572 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname); 2573 2574 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay); 2575 /* from Linux driver */ 2576 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC); 2577 2578 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT); 2579 2580 rtw_enable_interrupts(sc); 2581 2582 rtw_pktfilt_load(sc); 2583 2584 rtw_hwring_setup(sc); 2585 2586 rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_wep_txkey); 2587 2588 rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1); 2589 2590 ifp->if_flags |= IFF_RUNNING; 2591 ic->ic_state = IEEE80211_S_INIT; 2592 2593 RTW_WRITE16(regs, RTW_BSSID16, 0x0); 2594 RTW_WRITE(regs, RTW_BSSID32, 0x0); 2595 2596 rtw_resume_ticks(sc); 2597 2598 rtw_set_nettype(sc, IEEE80211_M_MONITOR); 2599 2600 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2601 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2602 else 2603 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2604 2605 out: 2606 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 2607 return rc; 2608 } 2609 2610 static __inline void 2611 rtw_led_init(struct rtw_regs *regs) 2612 { 2613 uint8_t cfg0, cfg1; 2614 2615 rtw_set_access(regs, RTW_ACCESS_CONFIG); 2616 2617 cfg0 = RTW_READ8(regs, RTW_CONFIG0); 2618 cfg0 |= RTW_CONFIG0_LEDGPOEN; 2619 RTW_WRITE8(regs, RTW_CONFIG0, cfg0); 2620 2621 cfg1 = RTW_READ8(regs, RTW_CONFIG1); 2622 RTW_DPRINTF(RTW_DEBUG_LED, 2623 ("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1)); 2624 2625 cfg1 &= ~RTW_CONFIG1_LEDS_MASK; 2626 cfg1 |= RTW_CONFIG1_LEDS_TX_RX; 2627 RTW_WRITE8(regs, RTW_CONFIG1, cfg1); 2628 2629 rtw_set_access(regs, RTW_ACCESS_NONE); 2630 } 2631 2632 /* 2633 * IEEE80211_S_INIT: LED1 off 2634 * 2635 * IEEE80211_S_AUTH, 2636 * IEEE80211_S_ASSOC, 2637 * IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx 2638 * 2639 * IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx 2640 */ 2641 static void 2642 rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate) 2643 { 2644 struct rtw_led_state *ls; 2645 2646 ls = &sc->sc_led_state; 2647 2648 switch (nstate) { 2649 case IEEE80211_S_INIT: 2650 rtw_led_init(&sc->sc_regs); 2651 callout_stop(&ls->ls_slow_ch); 2652 callout_stop(&ls->ls_fast_ch); 2653 ls->ls_slowblink = 0; 2654 ls->ls_actblink = 0; 2655 ls->ls_default = 0; 2656 break; 2657 case IEEE80211_S_SCAN: 2658 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2659 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2660 /*FALLTHROUGH*/ 2661 case IEEE80211_S_AUTH: 2662 case IEEE80211_S_ASSOC: 2663 ls->ls_default = RTW_LED1; 2664 ls->ls_actblink = RTW_LED1; 2665 ls->ls_slowblink = RTW_LED1; 2666 break; 2667 case IEEE80211_S_RUN: 2668 ls->ls_slowblink = 0; 2669 break; 2670 } 2671 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2672 } 2673 2674 static void 2675 rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid) 2676 { 2677 uint8_t led_condition; 2678 bus_size_t ofs; 2679 uint8_t mask, newval, val; 2680 2681 led_condition = ls->ls_default; 2682 2683 if (ls->ls_state & RTW_LED_S_SLOW) 2684 led_condition ^= ls->ls_slowblink; 2685 if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX)) 2686 led_condition ^= ls->ls_actblink; 2687 2688 RTW_DPRINTF(RTW_DEBUG_LED, 2689 ("%s: LED condition %" PRIx8 "\n", __func__, led_condition)); 2690 2691 switch (hwverid) { 2692 default: 2693 case 'F': 2694 ofs = RTW_PSR; 2695 newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1; 2696 if (led_condition & RTW_LED0) 2697 newval &= ~RTW_PSR_LEDGPO0; 2698 if (led_condition & RTW_LED1) 2699 newval &= ~RTW_PSR_LEDGPO1; 2700 break; 2701 case 'D': 2702 ofs = RTW_9346CR; 2703 mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS; 2704 newval = RTW_9346CR_EEM_PROGRAM; 2705 if (led_condition & RTW_LED0) 2706 newval |= RTW_9346CR_EEDI; 2707 if (led_condition & RTW_LED1) 2708 newval |= RTW_9346CR_EECS; 2709 break; 2710 } 2711 val = RTW_READ8(regs, ofs); 2712 RTW_DPRINTF(RTW_DEBUG_LED, 2713 ("%s: read %" PRIx8 " from reg[%#02x]\n", __func__, val, ofs)); 2714 val &= ~mask; 2715 val |= newval; 2716 RTW_WRITE8(regs, ofs, val); 2717 RTW_DPRINTF(RTW_DEBUG_LED, 2718 ("%s: wrote %" PRIx8 " to reg[%#02x]\n", __func__, val, ofs)); 2719 RTW_SYNC(regs, ofs, ofs); 2720 } 2721 2722 static void 2723 rtw_led_fastblink(void *arg) 2724 { 2725 int ostate, s; 2726 struct rtw_softc *sc = (struct rtw_softc *)arg; 2727 struct rtw_led_state *ls = &sc->sc_led_state; 2728 2729 s = splnet(); 2730 ostate = ls->ls_state; 2731 ls->ls_state ^= ls->ls_event; 2732 2733 if ((ls->ls_event & RTW_LED_S_TX) == 0) 2734 ls->ls_state &= ~RTW_LED_S_TX; 2735 2736 if ((ls->ls_event & RTW_LED_S_RX) == 0) 2737 ls->ls_state &= ~RTW_LED_S_RX; 2738 2739 ls->ls_event = 0; 2740 2741 if (ostate != ls->ls_state) 2742 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2743 splx(s); 2744 2745 callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); 2746 } 2747 2748 static void 2749 rtw_led_slowblink(void *arg) 2750 { 2751 int s; 2752 struct rtw_softc *sc = (struct rtw_softc *)arg; 2753 struct rtw_led_state *ls = &sc->sc_led_state; 2754 2755 s = splnet(); 2756 ls->ls_state ^= RTW_LED_S_SLOW; 2757 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); 2758 splx(s); 2759 callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); 2760 } 2761 2762 static __inline void 2763 rtw_led_attach(struct rtw_softc *sc) 2764 { 2765 struct rtw_led_state *ls = &sc->sc_led_state; 2766 2767 callout_init(&ls->ls_fast_ch); 2768 callout_init(&ls->ls_slow_ch); 2769 callout_setfunc(&ls->ls_fast_ch, rtw_led_fastblink, (void *)sc); 2770 callout_setfunc(&ls->ls_slow_ch, rtw_led_slowblink, (void *)sc); 2771 } 2772 2773 static int 2774 rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2775 { 2776 int rc = 0, s; 2777 struct rtw_softc *sc = ifp->if_softc; 2778 struct ifreq *ifr = (struct ifreq *)data; 2779 2780 s = splnet(); 2781 switch (cmd) { 2782 case SIOCSIFFLAGS: 2783 if ((ifp->if_flags & IFF_UP) != 0) { 2784 if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 2785 rtw_pktfilt_load(sc); 2786 } else 2787 rc = rtw_init(ifp); 2788 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 2789 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0) { 2790 RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__); 2791 rtw_stop(ifp, 1); 2792 } 2793 break; 2794 case SIOCADDMULTI: 2795 case SIOCDELMULTI: 2796 if (cmd == SIOCADDMULTI) 2797 rc = ether_addmulti(ifr, &sc->sc_ic.ic_ec); 2798 else 2799 rc = ether_delmulti(ifr, &sc->sc_ic.ic_ec); 2800 if (rc != ENETRESET) 2801 break; 2802 if (ifp->if_flags & IFF_RUNNING) 2803 rtw_pktfilt_load(sc); 2804 rc = 0; 2805 break; 2806 case SIOCS80211NWKEY: 2807 if ((rc = ieee80211_ioctl(ifp, cmd, data)) != ENETRESET) 2808 break; 2809 rc = 0; 2810 if ((ifp->if_flags & IFF_RUNNING) == 0) 2811 break; 2812 rtw_wep_setkeys(sc, sc->sc_ic.ic_nw_keys, 2813 sc->sc_ic.ic_wep_txkey); 2814 break; 2815 default: 2816 if ((rc = ieee80211_ioctl(ifp, cmd, data)) != ENETRESET) 2817 break; 2818 if ((sc->sc_flags & RTW_F_ENABLED) != 0) 2819 rc = rtw_init(ifp); 2820 else 2821 rc = 0; 2822 break; 2823 } 2824 splx(s); 2825 return rc; 2826 } 2827 2828 /* Select a transmit ring with at least one h/w and s/w descriptor free. 2829 * Return 0 on success, -1 on failure. 2830 */ 2831 static __inline int 2832 rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp, 2833 struct rtw_txdesc_blk **tdbp, int pri) 2834 { 2835 struct rtw_txsoft_blk *tsb; 2836 struct rtw_txdesc_blk *tdb; 2837 2838 KASSERT(pri >= 0 && pri < RTW_NTXPRI); 2839 2840 tsb = &sc->sc_txsoft_blk[pri]; 2841 tdb = &sc->sc_txdesc_blk[pri]; 2842 2843 if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) { 2844 *tsbp = NULL; 2845 *tdbp = NULL; 2846 return -1; 2847 } 2848 *tsbp = tsb; 2849 *tdbp = tdb; 2850 return 0; 2851 } 2852 2853 static __inline struct mbuf * 2854 rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri, 2855 struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp, 2856 struct ieee80211_node **nip, short *if_flagsp) 2857 { 2858 struct mbuf *m; 2859 2860 if (IF_IS_EMPTY(ifq)) 2861 return NULL; 2862 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) { 2863 *if_flagsp |= IFF_OACTIVE; 2864 return NULL; 2865 } 2866 IF_DEQUEUE(ifq, m); 2867 *nip = (struct ieee80211_node *)m->m_pkthdr.rcvif; 2868 m->m_pkthdr.rcvif = NULL; 2869 return m; 2870 } 2871 2872 /* Point *mp at the next 802.11 frame to transmit. Point *tsbp 2873 * at the driver's selection of transmit control block for the packet. 2874 */ 2875 static __inline int 2876 rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp, 2877 struct rtw_txdesc_blk **tdbp, struct mbuf **mp, 2878 struct ieee80211_node **nip) 2879 { 2880 struct mbuf *m0; 2881 struct rtw_softc *sc; 2882 short *if_flagsp; 2883 2884 sc = (struct rtw_softc *)ifp->if_softc; 2885 2886 DPRINTF(sc, RTW_DEBUG_XMIT, 2887 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 2888 2889 if_flagsp = &ifp->if_flags; 2890 2891 if (sc->sc_ic.ic_state == IEEE80211_S_RUN && 2892 (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp, 2893 tdbp, nip, if_flagsp)) != NULL) { 2894 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n", 2895 __func__)); 2896 return 0; 2897 } 2898 2899 if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp, 2900 tdbp, nip, if_flagsp)) != NULL) { 2901 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n", 2902 __func__)); 2903 return 0; 2904 } 2905 2906 if (sc->sc_ic.ic_state != IEEE80211_S_RUN) { 2907 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__)); 2908 return 0; 2909 } 2910 2911 if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_pwrsaveq, RTW_TXPRIHI, 2912 tsbp, tdbp, nip, if_flagsp)) != NULL) { 2913 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue pwrsave frame\n", 2914 __func__)); 2915 return 0; 2916 } 2917 2918 if (rtw_txring_choose(sc, tsbp, tdbp, RTW_TXPRIMD) == -1) { 2919 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no descriptor\n", __func__)); 2920 *if_flagsp |= IFF_OACTIVE; 2921 return 0; 2922 } 2923 2924 *mp = NULL; 2925 2926 IFQ_DEQUEUE(&ifp->if_snd, m0); 2927 if (m0 == NULL) { 2928 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame/ring ready\n", 2929 __func__)); 2930 return 0; 2931 } 2932 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__)); 2933 ifp->if_opackets++; 2934 #if NBPFILTER > 0 2935 if (ifp->if_bpf) 2936 bpf_mtap(ifp->if_bpf, m0); 2937 #endif 2938 if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) { 2939 DPRINTF(sc, RTW_DEBUG_XMIT, 2940 ("%s: encap error\n", __func__)); 2941 ifp->if_oerrors++; 2942 return -1; 2943 } 2944 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 2945 *mp = m0; 2946 return 0; 2947 } 2948 2949 static int 2950 rtw_seg_too_short(bus_dmamap_t dmamap) 2951 { 2952 int i; 2953 for (i = 0; i < dmamap->dm_nsegs; i++) { 2954 if (dmamap->dm_segs[i].ds_len < 4) { 2955 printf("%s: segment too short\n", __func__); 2956 return 1; 2957 } 2958 } 2959 return 0; 2960 } 2961 2962 /* TBD factor with atw_start */ 2963 static struct mbuf * 2964 rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain, 2965 u_int ndescfree, short *ifflagsp, const char *dvname) 2966 { 2967 int first, rc; 2968 struct mbuf *m, *m0; 2969 2970 m0 = chain; 2971 2972 /* 2973 * Load the DMA map. Copy and try (once) again if the packet 2974 * didn't fit in the alloted number of segments. 2975 */ 2976 for (first = 1; 2977 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0, 2978 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 || 2979 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first; 2980 first = 0) { 2981 if (rc == 0) 2982 bus_dmamap_unload(dmat, dmam); 2983 MGETHDR(m, M_DONTWAIT, MT_DATA); 2984 if (m == NULL) { 2985 printf("%s: unable to allocate Tx mbuf\n", 2986 dvname); 2987 break; 2988 } 2989 if (m0->m_pkthdr.len > MHLEN) { 2990 MCLGET(m, M_DONTWAIT); 2991 if ((m->m_flags & M_EXT) == 0) { 2992 printf("%s: cannot allocate Tx cluster\n", 2993 dvname); 2994 m_freem(m); 2995 break; 2996 } 2997 } 2998 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); 2999 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 3000 m_freem(m0); 3001 m0 = m; 3002 m = NULL; 3003 } 3004 if (rc != 0) { 3005 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc); 3006 m_freem(m0); 3007 return NULL; 3008 } else if (rtw_seg_too_short(dmam)) { 3009 printf("%s: cannot load Tx buffer, segment too short\n", 3010 dvname); 3011 bus_dmamap_unload(dmat, dmam); 3012 m_freem(m0); 3013 return NULL; 3014 } else if (dmam->dm_nsegs > ndescfree) { 3015 *ifflagsp |= IFF_OACTIVE; 3016 bus_dmamap_unload(dmat, dmam); 3017 m_freem(m0); 3018 return NULL; 3019 } 3020 return m0; 3021 } 3022 3023 #ifdef RTW_DEBUG 3024 static void 3025 rtw_print_txdesc(struct rtw_softc *sc, const char *action, 3026 struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc) 3027 { 3028 struct rtw_txdesc *td = &tdb->tdb_desc[desc]; 3029 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] ctl0 %#08x " 3030 "ctl1 %#08x buf %#08x len %#08x\n", 3031 sc->sc_dev.dv_xname, ts, action, desc, 3032 le32toh(td->td_ctl0), 3033 le32toh(td->td_ctl1), le32toh(td->td_buf), 3034 le32toh(td->td_len))); 3035 } 3036 #endif /* RTW_DEBUG */ 3037 3038 static void 3039 rtw_start(struct ifnet *ifp) 3040 { 3041 uint8_t tppoll; 3042 int desc, i, lastdesc, npkt, rate; 3043 uint32_t proto_ctl0, ctl0, ctl1; 3044 bus_dmamap_t dmamap; 3045 struct ieee80211com *ic; 3046 struct ieee80211_duration *d0; 3047 struct ieee80211_frame *wh; 3048 struct ieee80211_node *ni; 3049 struct mbuf *m0; 3050 struct rtw_softc *sc; 3051 struct rtw_txsoft_blk *tsb; 3052 struct rtw_txdesc_blk *tdb; 3053 struct rtw_txsoft *ts; 3054 struct rtw_txdesc *td; 3055 3056 sc = (struct rtw_softc *)ifp->if_softc; 3057 ic = &sc->sc_ic; 3058 3059 DPRINTF(sc, RTW_DEBUG_XMIT, 3060 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__)); 3061 3062 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 3063 goto out; 3064 3065 /* XXX do real rate control */ 3066 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS; 3067 3068 rate = MAX(2, ieee80211_get_rate(ic)); 3069 3070 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0) 3071 proto_ctl0 |= RTW_TXCTL0_SPLCP; 3072 3073 for (;;) { 3074 if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1) 3075 continue; 3076 if (m0 == NULL) 3077 break; 3078 ts = SIMPLEQ_FIRST(&tsb->tsb_freeq); 3079 3080 dmamap = ts->ts_dmamap; 3081 3082 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0, 3083 tdb->tdb_nfree, &ifp->if_flags, sc->sc_dev.dv_xname); 3084 3085 if (m0 == NULL || dmamap->dm_nsegs == 0) { 3086 DPRINTF(sc, RTW_DEBUG_XMIT, 3087 ("%s: fail dmamap load\n", __func__)); 3088 goto post_dequeue_err; 3089 } 3090 3091 #ifdef RTW_DEBUG 3092 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 3093 (IFF_DEBUG|IFF_LINK2)) { 3094 ieee80211_dump_pkt(mtod(m0, uint8_t *), 3095 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len 3096 : sizeof(wh), 3097 rate, 0); 3098 } 3099 #endif /* RTW_DEBUG */ 3100 ctl0 = proto_ctl0 | 3101 LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK); 3102 3103 wh = mtod(m0, struct ieee80211_frame *); 3104 3105 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 3106 IEEE80211_FC0_TYPE_MGT) { 3107 ctl0 |= RTW_TXCTL0_RATE_1MBPS; 3108 } else switch (rate) { 3109 default: 3110 case 2: 3111 ctl0 |= RTW_TXCTL0_RATE_1MBPS; 3112 break; 3113 case 4: 3114 ctl0 |= RTW_TXCTL0_RATE_2MBPS; 3115 break; 3116 case 11: 3117 ctl0 |= RTW_TXCTL0_RATE_5MBPS; 3118 break; 3119 case 22: 3120 ctl0 |= RTW_TXCTL0_RATE_11MBPS; 3121 break; 3122 } 3123 3124 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) 3125 ctl0 |= LSHIFT(sc->sc_txkey, RTW_TXCTL0_KEYID_MASK); 3126 3127 if (ieee80211_compute_duration(wh, m0->m_pkthdr.len, 3128 ic->ic_flags, ic->ic_fragthreshold, 3129 rate, &ts->ts_d0, &ts->ts_dn, &npkt, 3130 (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) == 3131 (IFF_DEBUG|IFF_LINK2)) == -1) { 3132 DPRINTF(sc, RTW_DEBUG_XMIT, 3133 ("%s: fail compute duration\n", __func__)); 3134 goto post_load_err; 3135 } 3136 3137 /* XXX >= ? */ 3138 if (m0->m_pkthdr.len > ic->ic_rtsthreshold) 3139 ctl0 |= RTW_TXCTL0_RTSEN; 3140 3141 d0 = &ts->ts_d0; 3142 3143 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur); 3144 3145 ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) | 3146 LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK); 3147 3148 if (d0->d_residue) 3149 ctl1 |= RTW_TXCTL1_LENGEXT; 3150 3151 /* TBD fragmentation */ 3152 3153 ts->ts_first = tdb->tdb_next; 3154 3155 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3156 BUS_DMASYNC_PREWRITE); 3157 3158 KASSERT(ts->ts_first < tdb->tdb_ndesc); 3159 3160 #if NBPFILTER > 0 3161 if (ic->ic_rawbpf != NULL) 3162 bpf_mtap((caddr_t)ic->ic_rawbpf, m0); 3163 3164 if (sc->sc_radiobpf != NULL) { 3165 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap; 3166 3167 rt->rt_flags = 0; 3168 rt->rt_rate = rate; 3169 rt->rt_chan_freq = 3170 htole16(ic->ic_bss->ni_chan->ic_freq); 3171 rt->rt_chan_flags = 3172 htole16(ic->ic_bss->ni_chan->ic_flags); 3173 3174 bpf_mtap2(sc->sc_radiobpf, (caddr_t)rt, 3175 sizeof(sc->sc_txtapu), m0); 3176 } 3177 #endif /* NPBFILTER > 0 */ 3178 3179 for (i = 0, lastdesc = desc = ts->ts_first; 3180 i < dmamap->dm_nsegs; 3181 i++, desc = RTW_NEXT_IDX(tdb, desc)) { 3182 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) { 3183 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, 3184 ("%s: seg too long\n", __func__)); 3185 goto post_load_err; 3186 } 3187 td = &tdb->tdb_desc[desc]; 3188 td->td_ctl0 = htole32(ctl0); 3189 if (i != 0) 3190 td->td_ctl0 |= htole32(RTW_TXCTL0_OWN); 3191 td->td_ctl1 = htole32(ctl1); 3192 td->td_buf = htole32(dmamap->dm_segs[i].ds_addr); 3193 td->td_len = htole32(dmamap->dm_segs[i].ds_len); 3194 lastdesc = desc; 3195 #ifdef RTW_DEBUG 3196 rtw_print_txdesc(sc, "load", ts, tdb, desc); 3197 #endif /* RTW_DEBUG */ 3198 } 3199 3200 KASSERT(desc < tdb->tdb_ndesc); 3201 3202 ts->ts_ni = ni; 3203 ts->ts_mbuf = m0; 3204 ts->ts_last = lastdesc; 3205 tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS); 3206 tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3207 htole32(RTW_TXCTL0_FS); 3208 3209 #ifdef RTW_DEBUG 3210 rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first); 3211 rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last); 3212 #endif /* RTW_DEBUG */ 3213 3214 tdb->tdb_nfree -= dmamap->dm_nsegs; 3215 tdb->tdb_next = desc; 3216 3217 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs, 3218 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3219 3220 tdb->tdb_desc[ts->ts_first].td_ctl0 |= 3221 htole32(RTW_TXCTL0_OWN); 3222 3223 #ifdef RTW_DEBUG 3224 rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first); 3225 #endif /* RTW_DEBUG */ 3226 3227 rtw_txdescs_sync(tdb, ts->ts_first, 1, 3228 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3229 3230 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q); 3231 SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q); 3232 3233 if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN]) { 3234 sc->sc_led_state.ls_event |= RTW_LED_S_TX; 3235 tsb->tsb_tx_timer = 5; 3236 ifp->if_timer = 1; 3237 } 3238 3239 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL); 3240 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, 3241 tppoll | (tsb->tsb_poll & RTW_TPPOLL_ALL)); 3242 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL); 3243 } 3244 out: 3245 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__)); 3246 return; 3247 post_load_err: 3248 bus_dmamap_unload(sc->sc_dmat, dmamap); 3249 m_freem(m0); 3250 post_dequeue_err: 3251 ieee80211_release_node(&sc->sc_ic, ni); 3252 return; 3253 } 3254 3255 static void 3256 rtw_watchdog(struct ifnet *ifp) 3257 { 3258 uint8_t tppoll; 3259 int pri; 3260 struct rtw_softc *sc; 3261 struct rtw_txsoft_blk *tsb; 3262 3263 sc = ifp->if_softc; 3264 3265 ifp->if_timer = 0; 3266 3267 if ((sc->sc_flags & RTW_F_ENABLED) == 0) 3268 return; 3269 3270 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3271 tsb = &sc->sc_txsoft_blk[pri]; 3272 3273 if (tsb->tsb_tx_timer == 0) 3274 continue; 3275 3276 if (--tsb->tsb_tx_timer == 0) { 3277 if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) 3278 continue; 3279 printf("%s: transmit timeout, priority %d\n", 3280 ifp->if_xname, pri); 3281 ifp->if_oerrors++; 3282 /* Stop Tx DMA, disable transmitter, clear 3283 * Tx rings, and restart. 3284 * 3285 * TBD Stop/restart just the broken ring? 3286 */ 3287 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL); 3288 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, 3289 tppoll | RTW_TPPOLL_SALL); 3290 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL); 3291 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0); 3292 rtw_txdescs_reset(sc); 3293 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1); 3294 rtw_start(ifp); 3295 } else 3296 ifp->if_timer = 1; 3297 } 3298 ieee80211_watchdog(ifp); 3299 return; 3300 } 3301 3302 static void 3303 rtw_start_beacon(struct rtw_softc *sc, int enable) 3304 { 3305 /* TBD */ 3306 return; 3307 } 3308 3309 static void 3310 rtw_next_scan(void *arg) 3311 { 3312 struct ieee80211com *ic = arg; 3313 int s; 3314 3315 /* don't call rtw_start w/o network interrupts blocked */ 3316 s = splnet(); 3317 if (ic->ic_state == IEEE80211_S_SCAN) 3318 ieee80211_next_scan(ic); 3319 splx(s); 3320 } 3321 3322 static void 3323 rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, enum ieee80211_opmode opmode, 3324 uint16_t intval0) 3325 { 3326 uint16_t bcnitv, intval; 3327 int i; 3328 struct rtw_regs *regs = &sc->sc_regs; 3329 3330 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 3331 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]); 3332 3333 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32); 3334 3335 rtw_set_access(regs, RTW_ACCESS_CONFIG); 3336 3337 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK)); 3338 3339 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK; 3340 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK); 3341 RTW_WRITE16(regs, RTW_BCNITV, bcnitv); 3342 /* magic from Linux */ 3343 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND)); 3344 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV)); 3345 3346 rtw_set_nettype(sc, opmode); 3347 3348 rtw_set_access(regs, RTW_ACCESS_NONE); 3349 3350 /* TBD WEP */ 3351 RTW_WRITE8(regs, RTW_SCR, 0); 3352 3353 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1); 3354 } 3355 3356 /* Synchronize the hardware state with the software state. */ 3357 static int 3358 rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 3359 { 3360 struct ifnet *ifp = &ic->ic_if; 3361 struct rtw_softc *sc = ifp->if_softc; 3362 struct mbuf *m; 3363 enum ieee80211_state ostate; 3364 int error; 3365 3366 ostate = ic->ic_state; 3367 3368 rtw_led_newstate(sc, nstate); 3369 3370 if (nstate == IEEE80211_S_INIT) { 3371 callout_stop(&sc->sc_scan_ch); 3372 sc->sc_cur_chan = IEEE80211_CHAN_ANY; 3373 rtw_start_beacon(sc, 0); 3374 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3375 } 3376 3377 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT) 3378 rtw_pwrstate(sc, RTW_ON); 3379 3380 if ((error = rtw_tune(sc)) != 0) 3381 return error; 3382 3383 switch (nstate) { 3384 case IEEE80211_S_ASSOC: 3385 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode, 3386 ic->ic_bss->ni_intval); 3387 break; 3388 case IEEE80211_S_INIT: 3389 panic("%s: unexpected state IEEE80211_S_INIT\n", __func__); 3390 break; 3391 case IEEE80211_S_SCAN: 3392 if (ostate != IEEE80211_S_SCAN) { 3393 (void)memset(ic->ic_bss->ni_bssid, 0, 3394 IEEE80211_ADDR_LEN); 3395 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode, 3396 ic->ic_bss->ni_intval); 3397 } 3398 3399 callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000, 3400 rtw_next_scan, ic); 3401 3402 break; 3403 case IEEE80211_S_RUN: 3404 switch (ic->ic_opmode) { 3405 case IEEE80211_M_HOSTAP: 3406 case IEEE80211_M_IBSS: 3407 m = rtw_beacon_alloc(sc, ic->ic_bss); 3408 if (m == NULL) { 3409 printf("%s: could not allocate beacon\n", 3410 sc->sc_dev.dv_xname); 3411 } else 3412 IF_ENQUEUE(&sc->sc_beaconq, m); 3413 /*FALLTHROUGH*/ 3414 case IEEE80211_M_AHDEMO: 3415 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode, 3416 ic->ic_bss->ni_intval); 3417 break; 3418 case IEEE80211_M_MONITOR: 3419 case IEEE80211_M_STA: 3420 break; 3421 } 3422 break; 3423 case IEEE80211_S_AUTH: 3424 break; 3425 } 3426 3427 if (nstate != IEEE80211_S_SCAN) 3428 callout_stop(&sc->sc_scan_ch); 3429 3430 if (nstate == IEEE80211_S_RUN && 3431 (ic->ic_opmode == IEEE80211_M_HOSTAP || 3432 ic->ic_opmode == IEEE80211_M_IBSS)) 3433 rtw_start_beacon(sc, 1); 3434 else 3435 rtw_start_beacon(sc, 0); 3436 3437 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg); 3438 } 3439 3440 /* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */ 3441 static uint64_t 3442 rtw_tsf_extend(struct rtw_regs *regs, uint32_t rstamp) 3443 { 3444 uint32_t tsftl, tsfth; 3445 3446 tsfth = RTW_READ(regs, RTW_TSFTRH); 3447 tsftl = RTW_READ(regs, RTW_TSFTRL); 3448 if (tsftl < rstamp) /* Compensate for rollover. */ 3449 tsfth--; 3450 return ((uint64_t)tsfth << 32) | rstamp; 3451 } 3452 3453 static void 3454 rtw_ibss_merge(struct rtw_softc *sc, struct ieee80211_node *ni, uint32_t rstamp) 3455 { 3456 struct ieee80211com *ic = &sc->sc_ic; 3457 3458 if (le64toh(ni->ni_tsf) >= rtw_tsf_extend(&sc->sc_regs, rstamp) && 3459 ieee80211_ibss_merge(ic, ni) == ENETRESET) { 3460 rtw_join_bss(sc, ic->ic_bss->ni_bssid, ic->ic_opmode, 3461 ic->ic_bss->ni_intval); 3462 } 3463 return; 3464 } 3465 3466 static void 3467 rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, 3468 struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp) 3469 { 3470 struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc; 3471 3472 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 3473 3474 switch (subtype) { 3475 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 3476 case IEEE80211_FC0_SUBTYPE_BEACON: 3477 if (ic->ic_opmode != IEEE80211_M_IBSS || 3478 ic->ic_state != IEEE80211_S_RUN) 3479 return; 3480 rtw_ibss_merge(sc, ni, rstamp); 3481 break; 3482 default: 3483 break; 3484 } 3485 return; 3486 } 3487 3488 static struct ieee80211_node * 3489 rtw_node_alloc(struct ieee80211com *ic) 3490 { 3491 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 3492 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic); 3493 3494 DPRINTF(sc, RTW_DEBUG_NODE, 3495 ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni)); 3496 return ni; 3497 } 3498 3499 static void 3500 rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni) 3501 { 3502 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc; 3503 3504 DPRINTF(sc, RTW_DEBUG_NODE, 3505 ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni, 3506 ether_sprintf(ni->ni_bssid))); 3507 (*sc->sc_mtbl.mt_node_free)(ic, ni); 3508 } 3509 3510 static int 3511 rtw_media_change(struct ifnet *ifp) 3512 { 3513 int error; 3514 3515 error = ieee80211_media_change(ifp); 3516 if (error == ENETRESET) { 3517 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 3518 (IFF_RUNNING|IFF_UP)) 3519 rtw_init(ifp); /* XXX lose error */ 3520 error = 0; 3521 } 3522 return error; 3523 } 3524 3525 static void 3526 rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr) 3527 { 3528 struct rtw_softc *sc = ifp->if_softc; 3529 3530 if ((sc->sc_flags & RTW_F_ENABLED) == 0) { 3531 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 3532 imr->ifm_status = 0; 3533 return; 3534 } 3535 ieee80211_media_status(ifp, imr); 3536 } 3537 3538 void 3539 rtw_power(int why, void *arg) 3540 { 3541 struct rtw_softc *sc = arg; 3542 struct ifnet *ifp = &sc->sc_ic.ic_if; 3543 int s; 3544 3545 DPRINTF(sc, RTW_DEBUG_PWR, 3546 ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why)); 3547 3548 s = splnet(); 3549 switch (why) { 3550 case PWR_STANDBY: 3551 /* XXX do nothing. */ 3552 break; 3553 case PWR_SUSPEND: 3554 rtw_stop(ifp, 0); 3555 if (sc->sc_power != NULL) 3556 (*sc->sc_power)(sc, why); 3557 break; 3558 case PWR_RESUME: 3559 if (ifp->if_flags & IFF_UP) { 3560 if (sc->sc_power != NULL) 3561 (*sc->sc_power)(sc, why); 3562 rtw_init(ifp); 3563 } 3564 break; 3565 case PWR_SOFTSUSPEND: 3566 case PWR_SOFTSTANDBY: 3567 case PWR_SOFTRESUME: 3568 break; 3569 } 3570 splx(s); 3571 } 3572 3573 /* rtw_shutdown: make sure the interface is stopped at reboot time. */ 3574 void 3575 rtw_shutdown(void *arg) 3576 { 3577 struct rtw_softc *sc = arg; 3578 3579 rtw_stop(&sc->sc_ic.ic_if, 1); 3580 } 3581 3582 static __inline void 3583 rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc) 3584 { 3585 (void)memcpy(ifp->if_xname, dvname, IFNAMSIZ); 3586 ifp->if_softc = softc; 3587 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | 3588 IFF_NOTRAILERS; 3589 ifp->if_ioctl = rtw_ioctl; 3590 ifp->if_start = rtw_start; 3591 ifp->if_watchdog = rtw_watchdog; 3592 ifp->if_init = rtw_init; 3593 ifp->if_stop = rtw_stop; 3594 } 3595 3596 static __inline void 3597 rtw_set80211props(struct ieee80211com *ic) 3598 { 3599 int nrate; 3600 ic->ic_phytype = IEEE80211_T_DS; 3601 ic->ic_opmode = IEEE80211_M_STA; 3602 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS | 3603 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP; 3604 3605 nrate = 0; 3606 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3607 IEEE80211_RATE_BASIC | 2; 3608 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 3609 IEEE80211_RATE_BASIC | 4; 3610 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11; 3611 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22; 3612 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 3613 } 3614 3615 static __inline void 3616 rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic) 3617 { 3618 mtbl->mt_newstate = ic->ic_newstate; 3619 ic->ic_newstate = rtw_newstate; 3620 3621 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt; 3622 ic->ic_recv_mgmt = rtw_recv_mgmt; 3623 3624 mtbl->mt_node_free = ic->ic_node_free; 3625 ic->ic_node_free = rtw_node_free; 3626 3627 mtbl->mt_node_alloc = ic->ic_node_alloc; 3628 ic->ic_node_alloc = rtw_node_alloc; 3629 } 3630 3631 static __inline void 3632 rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname, 3633 void *arg) 3634 { 3635 /* 3636 * Make sure the interface is shutdown during reboot. 3637 */ 3638 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg); 3639 if (hooks->rh_shutdown == NULL) 3640 printf("%s: WARNING: unable to establish shutdown hook\n", 3641 dvname); 3642 3643 /* 3644 * Add a suspend hook to make sure we come back up after a 3645 * resume. 3646 */ 3647 hooks->rh_power = powerhook_establish(rtw_power, arg); 3648 if (hooks->rh_power == NULL) 3649 printf("%s: WARNING: unable to establish power hook\n", 3650 dvname); 3651 } 3652 3653 static __inline void 3654 rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname, 3655 void *arg) 3656 { 3657 if (hooks->rh_shutdown != NULL) 3658 shutdownhook_disestablish(hooks->rh_shutdown); 3659 3660 if (hooks->rh_power != NULL) 3661 powerhook_disestablish(hooks->rh_power); 3662 } 3663 3664 static __inline void 3665 rtw_init_radiotap(struct rtw_softc *sc) 3666 { 3667 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 3668 sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu)); 3669 sc->sc_rxtap.rr_ihdr.it_present = htole32(RTW_RX_RADIOTAP_PRESENT); 3670 3671 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 3672 sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu)); 3673 sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT); 3674 } 3675 3676 static int 3677 rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen) 3678 { 3679 SIMPLEQ_INIT(&tsb->tsb_dirtyq); 3680 SIMPLEQ_INIT(&tsb->tsb_freeq); 3681 tsb->tsb_ndesc = qlen; 3682 tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF, 3683 M_NOWAIT); 3684 if (tsb->tsb_desc == NULL) 3685 return ENOMEM; 3686 return 0; 3687 } 3688 3689 static void 3690 rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc) 3691 { 3692 int pri; 3693 struct rtw_txsoft_blk *tsb; 3694 3695 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3696 tsb = &sc->sc_txsoft_blk[pri]; 3697 free(tsb->tsb_desc, M_DEVBUF); 3698 tsb->tsb_desc = NULL; 3699 } 3700 } 3701 3702 static int 3703 rtw_txsoft_blk_setup_all(struct rtw_softc *sc) 3704 { 3705 int pri, rc = 0; 3706 int qlen[RTW_NTXPRI] = 3707 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN}; 3708 struct rtw_txsoft_blk *tsbs; 3709 3710 tsbs = sc->sc_txsoft_blk; 3711 3712 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3713 rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]); 3714 if (rc != 0) 3715 break; 3716 } 3717 tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ; 3718 tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ; 3719 tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ; 3720 tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ; 3721 return rc; 3722 } 3723 3724 static void 3725 rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc, 3726 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase) 3727 { 3728 tdb->tdb_ndesc = ndesc; 3729 tdb->tdb_desc = desc; 3730 tdb->tdb_physbase = physbase; 3731 tdb->tdb_ofs = ofs; 3732 3733 (void)memset(tdb->tdb_desc, 0, 3734 sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc); 3735 3736 rtw_txdesc_blk_reset(tdb); 3737 } 3738 3739 static void 3740 rtw_txdesc_blk_setup_all(struct rtw_softc *sc) 3741 { 3742 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO], 3743 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO, 3744 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo)); 3745 3746 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD], 3747 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD, 3748 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd)); 3749 3750 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI], 3751 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI, 3752 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi)); 3753 3754 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN], 3755 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN, 3756 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn)); 3757 } 3758 3759 static struct rtw_rf * 3760 rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy) 3761 { 3762 rtw_rf_write_t rf_write; 3763 struct rtw_rf *rf; 3764 3765 switch (rfchipid) { 3766 default: 3767 rf_write = rtw_rf_hostwrite; 3768 break; 3769 case RTW_RFCHIPID_INTERSIL: 3770 case RTW_RFCHIPID_PHILIPS: 3771 case RTW_RFCHIPID_GCT: /* XXX a guess */ 3772 case RTW_RFCHIPID_RFMD: 3773 rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite; 3774 break; 3775 } 3776 3777 switch (rfchipid) { 3778 case RTW_RFCHIPID_MAXIM: 3779 rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0); 3780 sc->sc_pwrstate_cb = rtw_maxim_pwrstate; 3781 break; 3782 case RTW_RFCHIPID_PHILIPS: 3783 rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy); 3784 sc->sc_pwrstate_cb = rtw_philips_pwrstate; 3785 break; 3786 case RTW_RFCHIPID_RFMD: 3787 /* XXX RFMD has no RF constructor */ 3788 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate; 3789 /*FALLTHROUGH*/ 3790 default: 3791 return NULL; 3792 } 3793 rf->rf_continuous_tx_cb = 3794 (rtw_continuous_tx_cb_t)rtw_continuous_tx_enable; 3795 rf->rf_continuous_tx_arg = (void *)sc; 3796 return rf; 3797 } 3798 3799 /* Revision C and later use a different PHY delay setting than 3800 * revisions A and B. 3801 */ 3802 static uint8_t 3803 rtw_check_phydelay(struct rtw_regs *regs, uint32_t rcr0) 3804 { 3805 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV) 3806 #define REVC (REVAB | RTW_RCR_RXFTH_WHOLE) 3807 3808 uint8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY); 3809 3810 RTW_WRITE(regs, RTW_RCR, REVAB); 3811 RTW_WBW(regs, RTW_RCR, RTW_RCR); 3812 RTW_WRITE(regs, RTW_RCR, REVC); 3813 3814 RTW_WBR(regs, RTW_RCR, RTW_RCR); 3815 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC) 3816 phydelay |= RTW_PHYDELAY_REVC_MAGIC; 3817 3818 RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */ 3819 RTW_SYNC(regs, RTW_RCR, RTW_RCR); 3820 3821 return phydelay; 3822 #undef REVC 3823 } 3824 3825 void 3826 rtw_attach(struct rtw_softc *sc) 3827 { 3828 struct rtw_txsoft_blk *tsb; 3829 int pri, rc; 3830 3831 NEXT_ATTACH_STATE(sc, DETACHED); 3832 3833 switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) { 3834 case RTW_TCR_HWVERID_F: 3835 sc->sc_hwverid = 'F'; 3836 break; 3837 case RTW_TCR_HWVERID_D: 3838 sc->sc_hwverid = 'D'; 3839 break; 3840 default: 3841 sc->sc_hwverid = '?'; 3842 break; 3843 } 3844 printf("%s: hardware version %c\n", sc->sc_dev.dv_xname, 3845 sc->sc_hwverid); 3846 3847 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs), 3848 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs, 3849 0); 3850 3851 if (rc != 0) { 3852 printf("%s: could not allocate hw descriptors, error %d\n", 3853 sc->sc_dev.dv_xname, rc); 3854 goto err; 3855 } 3856 3857 NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC); 3858 3859 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs, 3860 sc->sc_desc_nsegs, sizeof(struct rtw_descs), 3861 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT); 3862 3863 if (rc != 0) { 3864 printf("%s: could not map hw descriptors, error %d\n", 3865 sc->sc_dev.dv_xname, rc); 3866 goto err; 3867 } 3868 NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP); 3869 3870 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1, 3871 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap); 3872 3873 if (rc != 0) { 3874 printf("%s: could not create DMA map for hw descriptors, " 3875 "error %d\n", sc->sc_dev.dv_xname, rc); 3876 goto err; 3877 } 3878 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE); 3879 3880 sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat; 3881 sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap; 3882 3883 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3884 sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat; 3885 sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap; 3886 } 3887 3888 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs, 3889 sizeof(struct rtw_descs), NULL, 0); 3890 3891 if (rc != 0) { 3892 printf("%s: could not load DMA map for hw descriptors, " 3893 "error %d\n", sc->sc_dev.dv_xname, rc); 3894 goto err; 3895 } 3896 NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD); 3897 3898 if (rtw_txsoft_blk_setup_all(sc) != 0) 3899 goto err; 3900 NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP); 3901 3902 rtw_txdesc_blk_setup_all(sc); 3903 3904 NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP); 3905 3906 sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0]; 3907 3908 for (pri = 0; pri < RTW_NTXPRI; pri++) { 3909 tsb = &sc->sc_txsoft_blk[pri]; 3910 3911 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat, 3912 &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) { 3913 printf("%s: could not load DMA map for " 3914 "hw tx descriptors, error %d\n", 3915 sc->sc_dev.dv_xname, rc); 3916 goto err; 3917 } 3918 } 3919 3920 NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE); 3921 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0], 3922 RTW_RXQLEN)) != 0) { 3923 printf("%s: could not load DMA map for hw rx descriptors, " 3924 "error %d\n", sc->sc_dev.dv_xname, rc); 3925 goto err; 3926 } 3927 NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE); 3928 3929 /* Reset the chip to a known state. */ 3930 if (rtw_reset(sc) != 0) 3931 goto err; 3932 NEXT_ATTACH_STATE(sc, FINISH_RESET); 3933 3934 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR); 3935 3936 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0) 3937 sc->sc_flags |= RTW_F_9356SROM; 3938 3939 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom, 3940 sc->sc_dev.dv_xname) != 0) 3941 goto err; 3942 3943 NEXT_ATTACH_STATE(sc, FINISH_READ_SROM); 3944 3945 if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr, 3946 &sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale, 3947 sc->sc_dev.dv_xname) != 0) { 3948 printf("%s: attach failed, malformed serial ROM\n", 3949 sc->sc_dev.dv_xname); 3950 goto err; 3951 } 3952 3953 printf("%s: %s PHY\n", sc->sc_dev.dv_xname, 3954 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"); 3955 3956 printf("%s: CS threshold %u\n", sc->sc_dev.dv_xname, sc->sc_csthr); 3957 3958 NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM); 3959 3960 sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid, 3961 sc->sc_flags & RTW_F_DIGPHY); 3962 3963 if (sc->sc_rf == NULL) { 3964 printf("%s: attach failed, could not attach RF\n", 3965 sc->sc_dev.dv_xname); 3966 goto err; 3967 } 3968 3969 NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH); 3970 3971 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr); 3972 3973 RTW_DPRINTF(RTW_DEBUG_ATTACH, 3974 ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay)); 3975 3976 if (sc->sc_locale == RTW_LOCALE_UNKNOWN) 3977 rtw_identify_country(&sc->sc_regs, &sc->sc_locale, 3978 sc->sc_dev.dv_xname); 3979 3980 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, 3981 sc->sc_dev.dv_xname); 3982 3983 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr, 3984 sc->sc_dev.dv_xname) != 0) 3985 goto err; 3986 NEXT_ATTACH_STATE(sc, FINISH_ID_STA); 3987 3988 rtw_setifprops(&sc->sc_if, sc->sc_dev.dv_xname, (void*)sc); 3989 3990 IFQ_SET_READY(&sc->sc_if.if_snd); 3991 3992 rtw_set80211props(&sc->sc_ic); 3993 3994 rtw_led_attach(sc); 3995 3996 /* 3997 * Call MI attach routines. 3998 */ 3999 if_attach(&sc->sc_if); 4000 ieee80211_ifattach(&sc->sc_if); 4001 4002 rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic); 4003 4004 /* possibly we should fill in our own sc_send_prresp, since 4005 * the RTL8180 is probably sending probe responses in ad hoc 4006 * mode. 4007 */ 4008 4009 /* complete initialization */ 4010 ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status); 4011 callout_init(&sc->sc_scan_ch); 4012 4013 rtw_init_radiotap(sc); 4014 4015 #if NBPFILTER > 0 4016 bpfattach2(&sc->sc_if, DLT_IEEE802_11_RADIO, 4017 sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf); 4018 #endif 4019 4020 rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc); 4021 4022 NEXT_ATTACH_STATE(sc, FINISHED); 4023 4024 return; 4025 err: 4026 rtw_detach(sc); 4027 return; 4028 } 4029 4030 int 4031 rtw_detach(struct rtw_softc *sc) 4032 { 4033 int pri; 4034 4035 sc->sc_flags |= RTW_F_INVALID; 4036 4037 switch (sc->sc_attach_state) { 4038 case FINISHED: 4039 rtw_stop(&sc->sc_if, 1); 4040 4041 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, 4042 (void*)sc); 4043 callout_stop(&sc->sc_scan_ch); 4044 ieee80211_ifdetach(&sc->sc_if); 4045 if_detach(&sc->sc_if); 4046 break; 4047 case FINISH_ID_STA: 4048 case FINISH_RF_ATTACH: 4049 rtw_rf_destroy(sc->sc_rf); 4050 sc->sc_rf = NULL; 4051 /*FALLTHROUGH*/ 4052 case FINISH_PARSE_SROM: 4053 case FINISH_READ_SROM: 4054 rtw_srom_free(&sc->sc_srom); 4055 /*FALLTHROUGH*/ 4056 case FINISH_RESET: 4057 case FINISH_RXMAPS_CREATE: 4058 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0], 4059 RTW_RXQLEN); 4060 /*FALLTHROUGH*/ 4061 case FINISH_TXMAPS_CREATE: 4062 for (pri = 0; pri < RTW_NTXPRI; pri++) { 4063 rtw_txdesc_dmamaps_destroy(sc->sc_dmat, 4064 sc->sc_txsoft_blk[pri].tsb_desc, 4065 sc->sc_txsoft_blk[pri].tsb_ndesc); 4066 } 4067 /*FALLTHROUGH*/ 4068 case FINISH_TXDESCBLK_SETUP: 4069 case FINISH_TXCTLBLK_SETUP: 4070 rtw_txsoft_blk_cleanup_all(sc); 4071 /*FALLTHROUGH*/ 4072 case FINISH_DESCMAP_LOAD: 4073 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap); 4074 /*FALLTHROUGH*/ 4075 case FINISH_DESCMAP_CREATE: 4076 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap); 4077 /*FALLTHROUGH*/ 4078 case FINISH_DESC_MAP: 4079 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs, 4080 sizeof(struct rtw_descs)); 4081 /*FALLTHROUGH*/ 4082 case FINISH_DESC_ALLOC: 4083 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs, 4084 sc->sc_desc_nsegs); 4085 /*FALLTHROUGH*/ 4086 case DETACHED: 4087 NEXT_ATTACH_STATE(sc, DETACHED); 4088 break; 4089 } 4090 return 0; 4091 } 4092 4093 int 4094 rtw_activate(struct device *self, enum devact act) 4095 { 4096 struct rtw_softc *sc = (struct rtw_softc *)self; 4097 int rc = 0, s; 4098 4099 s = splnet(); 4100 switch (act) { 4101 case DVACT_ACTIVATE: 4102 rc = EOPNOTSUPP; 4103 break; 4104 4105 case DVACT_DEACTIVATE: 4106 if_deactivate(&sc->sc_ic.ic_if); 4107 break; 4108 } 4109 splx(s); 4110 return rc; 4111 } 4112