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